initial commit

This commit is contained in:
valentineautos
2025-12-05 09:22:55 +00:00
parent 46949642a2
commit 16ffc2ab10
4033 changed files with 980542 additions and 0 deletions

View File

@@ -0,0 +1 @@
a19249042b9987097f89e682ec05d7fad1bd2186e7b758363a2ddb5787ef7d98

View File

@@ -0,0 +1,24 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# http://editorconfig.org
root = true
# Default configuration for all files
# - tabs for indentation
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# Some Mermaid diagram commands need to end with a trailing whitespace in Markdown files
[*.md]
trim_trailing_whitespace = false
# Use two spaces for YAML files
[{*.yml,*.yaml}]
indent_style = space
indent_size = 2

View File

@@ -0,0 +1,5 @@
build
dependencies.lock
managed_components
sdkconfig
sdkconfig.old

View File

@@ -0,0 +1,5 @@
espressif/esp_hosted:
version: ">=1.0"
override_path: "${OVERRIDE_PATH}"
rules:
- if: "target in [esp32p4, esp32h2]"

View File

@@ -0,0 +1,347 @@
# Holds jobs that run before promoting to main branch
### Notes:
# IDF v5.3 and v5.3.1 do not build for P4
# - fix only merged for v5.3.2 and above
# - https://github.com/espressif/esp-idf/commit/1aec9e7df38bb7ccc9ec2fb846288910c329d77a
regression_build_idf_v5.3_mqtt_tcp_h2:
variables:
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_VER: ["v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_TARGET: ["esp32h2"]
IDF_SLAVE_TARGET: ["esp32c6"]
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
regression_build_idf_v5.3_mqtt_tcp_p4:
variables:
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_VER: ["v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_TARGET: ["esp32p4"]
IDF_SLAVE_TARGET: ["esp32c6"]
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
regression_build_idf_v5.4_mqtt_tcp:
variables:
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4"]
IDF_TARGET: ["esp32p4", "esp32h2"]
IDF_SLAVE_TARGET: ["esp32c6"]
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
regression_build_idf_v5.5_iperf:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_VER: ["v5.5", "release-v5.5"]
IDF_TARGET: ["esp32p4", "esp32h2"]
IDF_SLAVE_TARGET: ["esp32", "esp32c2", "esp32c3", "esp32s3" ]
IDF_EXAMPLE_PATH: ["examples/wifi/iperf"]
regression_build_idf_master_mqtt_tcp:
variables:
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32p4", "esp32h2"]
IDF_SLAVE_TARGET: ["esp32", "esp32c2", "esp32c3", "esp32s3" ]
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
regression_build_idf_master_iperf:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32p4", "esp32h2"]
IDF_SLAVE_TARGET: ["esp32", "esp32c2", "esp32c3", "esp32s3" ]
IDF_EXAMPLE_PATH: ["examples/wifi/iperf"]
regression_build_coprocessor_idf_v5.3_pt1:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c6"]
IDF_VER: ["v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
SLAVE_CI_FILE: ["sdio", "spi", "spi_hd", "uart", "dpp"]
regression_build_coprocessor_idf_v5.3_pt2:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c2", "esp32c3", "esp32s3"]
IDF_VER: ["v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
SLAVE_CI_FILE: ["spi", "spi_hd", "uart"]
regression_build_coprocessor_idf_v5.3_esp32:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32"]
IDF_VER: ["v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
SLAVE_CI_FILE: ["sdio", "spi", "uart"]
regression_build_coprocessor_idf_v5.4_pt1:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c6"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4"]
SLAVE_CI_FILE: ["sdio", "spi", "spi_hd", "uart", "dpp"]
regression_build_coprocessor_idf_v5.4_pt2:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c2", "esp32c3", "esp32s3"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4"]
SLAVE_CI_FILE: ["spi", "spi_hd", "uart"]
regression_build_coprocessor_idf_v5.4_esp32:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4"]
SLAVE_CI_FILE: ["sdio", "spi", "uart"]
regression_build_coprocessor_idf_v5.5:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c2", "esp32c3", "esp32s3"]
IDF_VER: ["v5.5", "v5.5.1", "release-v5.5"]
SLAVE_CI_FILE: ["spi", "spi_hd", "uart"]
regression_build_coprocessor_idf_v5.5_esp32:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32"]
IDF_VER: ["v5.5", "v5.5.1", "release-v5.5"]
SLAVE_CI_FILE: ["sdio", "spi", "uart"]
regression_build_coprocessor_idf_master_all_features_enabled:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32c6"]
SLAVE_CI_FILE: ["all_features"]
regression_build_nimble_examples_h2:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32h2"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_nimble_bleprph_host_only_vhci",
"host_nimble_bleprph_host_only_uart_hci"]
regression_build_nimble_examples_p4:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_nimble_bleprph_host_only_vhci",
"host_nimble_bleprph_host_only_uart_hci"]
regression_build_bluedroid_examples_h2:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32h2"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32"]
EXAMPLE_TO_BUILD: ["host_bluedroid_ble_compatibility_test",
"host_bluedroid_bt_hid_mouse_device",
"host_bluedroid_host_only",
"host_bt_controller_mac_addr"]
regression_build_bluedroid_examples_p4:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32"]
EXAMPLE_TO_BUILD: ["host_bluedroid_ble_compatibility_test",
"host_bluedroid_bt_hid_mouse_device",
"host_bluedroid_host_only",
"host_bt_controller_mac_addr"]
regression_build_wifi_examples_h2:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32h2"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3", "v5.3.1", "v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_wifi_easy_connect_dpp_enrollee",
"host_wifi_itwt",
"host_transport_config",
"host_network_split__power_save"]
regression_build_wifi_examples_p4:
tags:
- build
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_wifi_easy_connect_dpp_enrollee",
"host_wifi_itwt",
"host_transport_config",
"host_network_split__power_save"]
# build an example using the various transports
# this is to verify transport builds as expected on the host
# for h2, build only for ESP-IDF v5.3 and v5.3.1
# for p4, build for other ESP-IDFs
regression_build_transport_examples_h2:
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32h2"]
IDF_VER: ["v5.3", "v5.3.1"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_network_split__power_save"]
EXAMPLE_CI_FILE: ["spi", "spi_hd", "uart"]
regression_build_transport_examples_p4:
rules:
- !reference [.staging_branch_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["v5.4", "v5.4.1", "v5.4.2", "release-v5.4",
"v5.3.2", "v5.3.3", "v5.3.4", "release-v5.3"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_network_split__power_save"]
EXAMPLE_CI_FILE: ["sdio", "spi", "spi_hd", "uart"]

View File

@@ -0,0 +1,26 @@
# Holds rules for running jobs
# default rule
# used for running jobs on a merge request to staging
.default_rules:
rules:
- if: $CI_COMMIT_BRANCH == "staging" && $CI_PIPELINE_SOURCE == "push"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "staging"
# staging branch rule
# used for running regression jobs on staging branch
.staging_branch_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_COMMIT_BRANCH == "staging" && $CI_PIPELINE_SOURCE == "push"
# no build rule to disable jobs temporarily
# while testing new build rules
.no_build_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_COMMIT_BRANCH == "staging" && $CI_PIPELINE_SOURCE == "push"
when: never

View File

@@ -0,0 +1,159 @@
# Holds jobs that run from a merge request
###
### Check project pre-requisites have been fulfilled
###
premerge_check:
rules:
- !reference [.default_rules, rules]
extends: .premerge_check_template
image: espressif/idf:latest
###
### Build host using ESP-IDF examples
###
### protocols/mqtt/tcp example
sanity_build_idf_master_mqtt_tcp:
variables:
EXAMPLE_CI_FILE: "sdkconfig.ci.p4_wifi"
rules:
- !reference [.default_rules, rules]
extends: .build_template
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_SLAVE_TARGET: ["esp32c6", "esp32c5"]
IDF_EXAMPLE_PATH: ["examples/protocols/mqtt/tcp"]
### wifi/iperf example
sanity_build_idf_v5.5_iperf:
rules:
- !reference [.default_rules, rules]
extends: .build_template
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_VER: ["v5.5", "v5.5.1", "release-v5.5"]
IDF_TARGET: ["esp32p4"]
IDF_SLAVE_TARGET: ["esp32c6", "esp32c5"]
IDF_EXAMPLE_PATH: ["examples/wifi/iperf"]
sanity_build_idf_master_iperf:
rules:
- !reference [.default_rules, rules]
extends: .build_template
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_SLAVE_TARGET: ["esp32c6", "esp32c5", "esp32c61"]
IDF_EXAMPLE_PATH: ["examples/wifi/iperf"]
###
### Build coprocessor
###
sanity_build_coprocessor_idf_v5.5:
rules:
- !reference [.default_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32c6", "esp32c5"]
IDF_VER: ["v5.5", "v5.5.1", "release-v5.5"]
SLAVE_CI_FILE: ["sdio", "spi", "spi_hd", "uart", "dpp"]
sanity_build_coprocessor_idf_master:
rules:
- !reference [.default_rules, rules]
extends: .build_template_coprocessor
image: espressif/idf:latest
parallel:
matrix:
- IDF_TARGET: ["esp32c6", "esp32c5", "esp32c61"]
SLAVE_CI_FILE: ["sdio", "spi", "spi_hd", "uart", "dpp"]
###
### build ESP-Hosted examples
###
sanity_build_nimble_examples:
rules:
- !reference [.default_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["latest",
"v5.5", "v5.5.1", "release-v5.5"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_nimble_bleprph_host_only_vhci",
"host_nimble_bleprph_host_only_uart_hci"]
sanity_build_bluedroid_examples:
rules:
- !reference [.default_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["latest",
"v5.5", "v5.5.1", "release-v5.5"]
IDF_SLAVE_TARGET: ["esp32"]
EXAMPLE_TO_BUILD: ["host_bluedroid_ble_compatibility_test",
"host_bluedroid_bt_hid_mouse_device",
"host_bluedroid_host_only",
"host_bt_controller_mac_addr"]
sanity_build_wifi_examples:
rules:
- !reference [.default_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["latest",
"v5.5", "v5.5.1", "release-v5.5"]
IDF_SLAVE_TARGET: ["esp32c6", "esp32c5"]
EXAMPLE_TO_BUILD: ["host_wifi_easy_connect_dpp_enrollee",
"host_wifi_itwt",
"host_transport_config",
"host_network_split__power_save",
"host_performs_slave_ota"]
# build an example using the various transports
# this is to verify transport builds as expected on the host
sanity_build_transport_examples:
rules:
- !reference [.default_rules, rules]
extends: .build_template_example
image: espressif/idf:${IDF_VER}
parallel:
matrix:
- IDF_TARGET: ["esp32p4"]
IDF_VER: ["latest",
"v5.5", "v5.5.1", "release-v5.5"]
IDF_SLAVE_TARGET: ["esp32c6"]
EXAMPLE_TO_BUILD: ["host_network_split__power_save"]
EXAMPLE_CI_FILE: ["sdio", "spi", "spi_hd", "uart"]
###
### Promote staging to main after successful regression testing
###
promote_staging_to_main:
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "staging" && $CI_PIPELINE_SOURCE == "push"
script:
- git remote set-url origin https://oauth2:${GITLAB_TOKEN_STAGING_TO_MAIN}@gitlab.espressif.cn:6688/app-frameworks/esp_hosted_mcu.git
- git push origin $CI_COMMIT_SHA:main
tags:
- build

View File

@@ -0,0 +1,154 @@
# Holds templates used for jobs
.premerge_check_template:
stage: pre
tags:
- build
script:
- source ${IDF_PATH}/export.sh
# check the exported fw versions
- python tools/check_fw_versions.py
# check the changelog
- python tools/check_changelog.py
.build_template_coprocessor:
stage: build_coprocessor
tags:
- build
artifacts:
when: always
expire_in: 4 days
script:
- export IDF_PYTHON_CHECK_CONSTRAINTS=yes
- ${IDF_PATH}/install.sh --enable-ci
- source ${IDF_PATH}/export.sh
- SDKCONFIG_PATTERN="sdkconfig.ci.${SLAVE_CI_FILE}"
# Build with IDF pedantic flags and IDF build apps script
- export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
- export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
- export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
- cd slave
# use --enable-preview-targets to build for all targets
- idf-build-apps find -p . --enable-preview-targets --config ${SDKCONFIG_PATTERN} -vv --target ${IDF_TARGET}
- idf-build-apps build -p . --enable-preview-targets --config ${SDKCONFIG_PATTERN} -vv --target ${IDF_TARGET}
.build_template_example:
stage: build_example
tags:
- build
artifacts:
when: always
expire_in: 4 days
script:
- export IDF_PYTHON_CHECK_CONSTRAINTS=yes
- ${IDF_PATH}/install.sh --enable-ci
- source ${IDF_PATH}/export.sh
# Need to rename the cloned "esp_hosted_mcu" directory since the injected component name is "esp_hosted"
- cd .. && rm -rf esp_hosted && mv esp_hosted_mcu esp_hosted && cd esp_hosted
# Create components directory and link esp_hosted component
- export OVERRIDE_PATH=`pwd`
- cd examples/${EXAMPLE_TO_BUILD}
# Create components directory and link esp_hosted component
- mkdir -p components
- ln -sf ${OVERRIDE_PATH} components/esp_hosted
# Override component dependency as backup only if not already present
- |
if ! grep -q "esp_hosted" main/idf_component.yml 2>/dev/null; then
cat ${OVERRIDE_PATH}/.gitlab-ci-override-idf-component.yml >> main/idf_component.yml
echo "Added esp_hosted override to idf_component.yml"
fi
# Add slave target configuration if specified
- |
if [ ! -z "${IDF_SLAVE_TARGET}" ]; then
echo "CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y" >> sdkconfig.defaults
echo "Added slave target CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y to sdkconfig.defaults"
fi
# Build with IDF pedantic flags and IDF build apps script
- export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
- export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
- export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
# Build with extra ci config file if specified
- |
if [ ! -z "${EXAMPLE_CI_FILE}" ]; then
idf-build-apps find -p . -vv --config sdkconfig.ci.${EXAMPLE_CI_FILE} --target ${IDF_TARGET}
idf-build-apps build -p . -vv --config sdkconfig.ci.${EXAMPLE_CI_FILE} --target ${IDF_TARGET}
else
idf-build-apps find -p . -vv --target ${IDF_TARGET}
idf-build-apps build -p . -vv --target ${IDF_TARGET}
fi
.build_template:
stage: build
tags:
- build
artifacts:
paths:
- "artifacts_*/"
when: always
expire_in: 4 days
script:
- export IDF_PYTHON_CHECK_CONSTRAINTS=yes
- ${IDF_PATH}/install.sh --enable-ci
- source ${IDF_PATH}/export.sh
# Need to rename the cloned "esp_hosted_mcu" directory since the injected component name is "esp_hosted"
- cd .. && rm -rf esp_hosted && mv esp_hosted_mcu esp_hosted && cd esp_hosted
# Replaces esp_hosted component in example's deps with the one from the current repository
- export OVERRIDE_PATH=`pwd`
- cd ${IDF_PATH}/${IDF_EXAMPLE_PATH}
# Create components directory and link esp_hosted component
- mkdir -p components
- ln -sf ${OVERRIDE_PATH} components/esp_hosted
- echo "Created components directory with esp_hosted link:"
- ls -la components/
# Override component dependency as backup only if not already present
- |
if ! grep -q "esp_hosted" main/idf_component.yml 2>/dev/null; then
cat ${OVERRIDE_PATH}/.gitlab-ci-override-idf-component.yml >> main/idf_component.yml
echo "Added esp_hosted override to idf_component.yml"
fi
# Add slave target configuration if specified
- |
if [ ! -z "${IDF_SLAVE_TARGET}" ]; then
echo "CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y" >> sdkconfig.defaults
echo "Added slave target CONFIG_SLAVE_IDF_TARGET_${IDF_SLAVE_TARGET^^}=y to sdkconfig.defaults"
fi
# HOSTED_CI_FILE: use custom sdkconfig CI file from esp_hosted directory, or
# EXAMPLE_CI_FILE: use sdkconfig CI file in example directory
- |
if [ ! -z "${SDKCONFIG_CI_FILE}" ]; then
cp ${OVERRIDE_PATH}/${SDKCONFIG_CI_FILE} ./sdkconfig.ci.custom
echo "Using custom sdkconfig: ${SDKCONFIG_CI_FILE}"
SDKCONFIG_PATTERN="sdkconfig.ci.custom"
elif [ ! -z "${EXAMPLE_CI_FILE}" ]; then
echo "Using CI sdkconfig file in example: ${EXAMPLE_CI_FILE}"
SDKCONFIG_PATTERN="./${EXAMPLE_CI_FILE}"
else
SDKCONFIG_PATTERN="sdkconfig.ci*"
fi
- echo "SDKCONFIG_PATTERN is ${SDKCONFIG_PATTERN}"
# Build with IDF pedantic flags and IDF build apps script
- export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
- export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
- export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
# Remove the conflicting extconn config that disables hosted
- rm -f sdkconfig.ci.*extconn*
# use --config-file to override default IDF config file
# use --enable-preview-targets to build for all targets
# use --override-sdkconfig-items to override (possibly incorrect) build target that may be in provided config file
- idf-build-apps find -p . --enable-preview-targets --config-file "${OVERRIDE_PATH}/.idf_build_apps.toml" --config ${SDKCONFIG_PATTERN} --override-sdkconfig-items=CONFIG_IDF_TARGET=${IDF_TARGET} -vv --target ${IDF_TARGET}
- idf-build-apps build -p . --enable-preview-targets --config-file "${OVERRIDE_PATH}/.idf_build_apps.toml" --config ${SDKCONFIG_PATTERN} --override-sdkconfig-items=CONFIG_IDF_TARGET=${IDF_TARGET} -vv --target ${IDF_TARGET}
# - echo "----------- last sdkconfig.defaults,ci* used (${IDF_TARGET}-${IDF_SLAVE_TARGET}) --------------"
# - cat sdkconfig.defaults
# - cat sdkconfig.ci*
# - echo "----------- last (generated) sdkconfig used (${IDF_TARGET}-${IDF_SLAVE_TARGET}) --------------"
# - cat sdkconfig
# - echo "----------------------------------------------"
# Copy config files back to project directory for artifacts
- mkdir -p ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}
- cp sdkconfig* ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}/ 2>/dev/null || echo "No sdkconfig files found"
- cp main/idf_component.yml ${OVERRIDE_PATH}/artifacts_${IDF_TARGET}_${IDF_SLAVE_TARGET}/ 2>/dev/null || echo "No component file found"
# Clean up the component symlink
- unlink components/esp_hosted
- echo "Cleaned up esp_hosted component symlink"
# Rename back, since post scripts expect the original name
- cd ${OVERRIDE_PATH} && cd .. && mv esp_hosted esp_hosted_mcu

View File

@@ -0,0 +1,3 @@
[submodule "esp_hosted_fg/common/protobuf-c"]
path = common/protobuf-c
url = https://github.com/protobuf-c/protobuf-c.git

View File

@@ -0,0 +1 @@
build_log_filename = ""

View File

@@ -0,0 +1,26 @@
repos:
- repo: local
hooks:
- id: version-checker
name: ESP-Hosted Version Checker
entry: tools/check_fw_versions.py
language: python
args: [ "--update" ]
always_run: true
pass_filenames: false
- id: rpc-checker
name: ESP-Hosted RPC Checker
entry: tools/check_rpc_calls.py
language: python
always_run: true
pass_filenames: false
- id: changelog-checker
name: ESP-Hosted Changelog Checker
entry: tools/check_changelog.py
language: python
files: ^idf_component.yml$
- repo: https://github.com/espressif/check-copyright/
rev: v1.1.1
hooks:
- id: check-copyright
args: ['--config', 'tools/check_copyright_config.yaml']

View File

@@ -0,0 +1,284 @@
# Changelog
## 2.6.5
### Features
- Add example showing concurrent use of a SD Card and ESP-Hosted.
## 2.6.4
- Fix the esp_wifi_deinit() call from host
## 2.6.3
### Bug Fixes
- Increase timing used to reset co-processors to work with a slower FreeRTOS clock tick
- Updated documentation on performance optimization
## 2.6.2
### Bug Fixes
- fixed bug in enabling `esp_eap_client_set_eap_methods` on co-processor based on ESP-IDF version
## 2.6.1
### Bug Fixes
Minor fixes in Slave OTA example
## 2.6.0
- Added public OTA APIs for slave firmware updates
- Added host-triggered slave OTA example with support for HTTP, partition, and filesystem sources
- Support for LittleFS filesystem-based OTA updates
- Migration guide updated for 2.6.0
### APIs added
- `esp_hosted_ota_begin`
- `esp_hosted_ota_write`
- `esp_hosted_ota_end`
- `esp_hosted_ota_activate`
### APIs deprecated
- `esp_hosted_slave_ota` - Use the new [Host Performs Slave OTA Example](examples/host_performs_slave_ota/README.md) instead for more flexible OTA implementations with comprehensive documentation and multiple deployment methods
### Examples added
- `host_performs_slave_ota` - Host-triggered slave OTA example supporting HTTP URLs, partition sources and LittleFS filesystem sources
## 2.5.12
### Features
- Add SPI (full and half duplex) and UART support for ESP32-C61
- Updated documentation on applying optimised Wi-Fi settings to sdkconfigs
### Bug Fixes
- Fixed build issues when raw throughput testing is enabled
- Fixed bug in co-processor causing SDIO to operate only in packet mode
## 2.5.11
### Bug Fixes
- Fixes to use compatible version of `idf-build-apps` and constraints during CI pipeline builds
- Renamed CI pipelines to "sanity" and "regression"
- Prefix jobs with `sanity_` or `regression_` to make their names unique
- Enabled building of ESP-Hosted examples in regression pipeline
- Various bug fixes found in the process of fixing the CI pipelines
## 2.5.10
### Features
- Version, 2.5.8 - 2.5.10:
- Add staging branch workflow for safer component releases
## 2.5.7
### Bug Fixes
- Fixed build break when Network Split and CLI Commands are enabled on coprocessor
## 2.5.6
### Bug Fixes
- Updated co-processor and some example `idf_component.yml` files to set component dependencies based on the ESP-IDF version in use
## 2.5.5
### Bug Fixes
- Fixed build errors when using latest version of ESP-IDF
- Updated Wi-Fi Easy Connect (DPP) code to match current ESP-IDF master
- Adjusted CI pipeline
## 2.5.4
### Features
- Added building with ESP-IDF v5.3 in CI
- Added building ESP-Hosted examples in CI
### Bug Fixes
- Fixed building with ESP32-H2 as host in CI (was skipping build)
## 2.5.3
### Bug Fixes
- Fix the ESP-IDF CI
## 2.5.2
### Features
- Add support to get and set the BT Controller Mac Address
- To support set BT Controller Mac Address, BT Controller is now disabled by default on the co-processor, and host must enable the BT Controller. See [Initializing the Bluetooth Controller](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/bluetooth_design.md#31-initializing-the-bluetooth-controller) for details
- Updated all ESP-Hosted BT related examples to account for new BT Controller behaviour
### APIs added
- `esp_hosted_bt_controller_init`
- `esp_hosted_bt_controller_deinit`
- `esp_hosted_bt_controller_enable`
- `esp_hosted_bt_controller_disable`
- `esp_hosted_iface_mac_addr_set`
- `esp_hosted_iface_mac_addr_get`
- `esp_hosted_iface_mac_addr_len_get`
## 2.5.1
### Bug Fixes
- Added dependency on `esp_driver_gpio`
## 2.5.0
### Bug Fixes
- Remove dependency on deprecated `driver` component and added necessary dependencies instead
## 2.4.3
### Features
- Add support for Wi-Fi Easy Connect (DPP)
- [Espressif documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_dpp.html) on Wi-Fi Easy Connect (DPP)
- [ESP-Hosted Enrollee Example](https://github.com/espressif/esp-hosted-mcu/tree/main/examples/host_wifi_easy_connect_dpp_enrollee) using DPP to securely onboard a ESP32P4 with C6 board to a network with the help of a QR code and an Android 10+ device
### APIs added
- `esp_supp_dpp_init`
- `esp_supp_dpp_deinit`
- `esp_supp_dpp_bootstrap_gen`
- `esp_supp_dpp_start_listen`
- `esp_supp_dpp_stop_listen`
## 2.4.2
### Bug Fixes
- Fix ignored lwip hook header in slave example
## 2.4.1
### Bug Fixes
- Reduced ESP32 bootloader size
## 2.4.0
### Features
- Added support for Wi-Fi Enterprise
### APIs added
- `esp_wifi_sta_enterprise_enable`
- `esp_wifi_sta_enterprise_disable`
- `esp_eap_client_set_identity`
- `esp_eap_client_clear_identity`
- `esp_eap_client_set_username`
- `esp_eap_client_clear_username`
- `esp_eap_client_set_password`
- `esp_eap_client_clear_password`
- `esp_eap_client_set_new_password`
- `esp_eap_client_clear_new_password`
- `esp_eap_client_set_ca_cert`
- `esp_eap_client_clear_ca_cert`
- `esp_eap_client_set_certificate_and_key`
- `esp_eap_client_clear_certificate_and_key`
- `esp_eap_client_set_disable_time_check`
- `esp_eap_client_get_disable_time_check`
- `esp_eap_client_set_ttls_phase2_method`
- `esp_eap_client_set_suiteb_192bit_certification`
- `esp_eap_client_set_pac_file`
- `esp_eap_client_set_fast_params`
- `esp_eap_client_use_default_cert_bundle`
- `esp_wifi_set_okc_support`
- `esp_eap_client_set_domain_name`
- `esp_eap_client_set_eap_methods`
## 2.3.3
### Features
- Added SDIO support for ESP32-C61
## 2.3.2
### Features
- Add host example to showcase transport config before `esp_hosted_init()`
## 2.3.1
### Bug Fixes
- Fixed a build break caused by refactoring
## 2.3.0
### Features
- Refactored common and port specific code
## 2.2.4
### Bug Fixes
- Fixed SPI Full Duplex startup sequence
- Fixed incorrect Handshake GPIO assignment for C5 on Module
- Added valid CPU freqencies in ITWT Example for H2
## 2.2.3
### Bug Fixes
- Fixed itwt build break for IDF v5.3.1
## 2.2.2
### Features
- Added support for Wi-Fi Power Save and ITWT
- Added ITWT example
- Updated copyright check to allow Unlicensed or CC0-1.0 files
### APIs added
- `esp_wifi_set_inactive_time()`
- `esp_wifi_get_inactive_time()`
- `esp_wifi_sta_twt_config()`
- `esp_wifi_sta_itwt_setup()`
- `esp_wifi_sta_itwt_teardown()`
- `esp_wifi_sta_itwt_suspend()`
- `esp_wifi_sta_itwt_get_flow_id_status()`
- `esp_wifi_sta_itwt_send_probe_req()`
- `esp_wifi_sta_itwt_set_target_wake_time_offset()`
## 2.2.1
### Features
- Allow external code to override Hosted BT Tx function by making it a `weak` reference
## 2.2.0
### Features
- Add support for fragmentation of packets from sdio host to slave
## 2.1.11
### Bug Fixes
- Fixed SoftAP operation after integration of lwIP split code

View File

@@ -0,0 +1,154 @@
if(CONFIG_ESP_HOSTED_ENABLED)
message(STATUS "Using Hosted Wi-Fi")
set(FG_root_dir ".")
set(host_dir "${FG_root_dir}/host")
set(srcs
"${host_dir}/api/src/esp_wifi_weak.c"
"${host_dir}/api/src/esp_hosted_api.c"
"${host_dir}/api/src/esp_hosted_transport_config.c"
"${host_dir}/api/src/esp_hosted_ota_api.c"
"${host_dir}/drivers/transport/transport_drv.c"
"${host_dir}/drivers/serial/serial_ll_if.c"
"${host_dir}/utils/stats.c"
"${host_dir}/drivers/serial/serial_drv.c")
# only these directories are public. Others are private
set(pub_include
"${host_dir}"
"${host_dir}/api/include")
set(priv_include
"${host_dir}/drivers/transport"
"${host_dir}/drivers/transport/spi"
"${host_dir}/drivers/transport/sdio"
"${host_dir}/drivers/serial"
"${host_dir}/utils"
"${host_dir}/api/priv")
# rpc files - wrap -> slaveif -> core
set(rpc_dir "${host_dir}/drivers/rpc")
set(rpc_core_dir "${rpc_dir}/core")
set(rpc_slaveif_dir "${rpc_dir}/slaveif")
set(rpc_wrap_dir "${rpc_dir}/wrap")
list(APPEND srcs
"${rpc_core_dir}/rpc_core.c"
"${rpc_core_dir}/rpc_req.c"
"${rpc_core_dir}/rpc_rsp.c"
"${rpc_core_dir}/rpc_evt.c"
"${rpc_core_dir}/rpc_utils.c"
"${rpc_slaveif_dir}/rpc_slave_if.c"
"${rpc_wrap_dir}/rpc_wrap.c")
list(APPEND priv_include
"${rpc_core_dir}"
"${rpc_slaveif_dir}"
"${rpc_wrap_dir}")
# virtual serial
set(virt_serial_dir "${host_dir}/drivers/virtual_serial_if")
list(APPEND srcs "${virt_serial_dir}/serial_if.c")
list(APPEND priv_include "${virt_serial_dir}")
# mempool
list(APPEND srcs "${host_dir}/drivers/mempool/mempool.c")
list(APPEND priv_include "${host_dir}/drivers/mempool" )
# slave and host common files
set(common_dir "${FG_root_dir}/common")
list(APPEND srcs
"${common_dir}/protobuf-c/protobuf-c/protobuf-c.c"
"${common_dir}/proto/esp_hosted_rpc.pb-c.c" )
list(APPEND priv_include
"${common_dir}"
"${common_dir}/log"
"${common_dir}/rpc"
"${common_dir}/transport"
"${common_dir}/protobuf-c"
"${common_dir}/proto" )
# cli
list(APPEND srcs "${common_dir}/utils/esp_hosted_cli.c")
list(APPEND priv_include "${common_dir}/utils")
# bt (NimBLE)
### TODO config for HCI over UART
list(APPEND priv_include "${host_dir}/drivers/bt")
if(CONFIG_ESP_HOSTED_NIMBLE_HCI_VHCI OR CONFIG_ESP_HOSTED_BLUEDROID_HCI_VHCI)
list(APPEND srcs "${host_dir}/drivers/bt/vhci_drv.c")
else()
list(APPEND srcs "${host_dir}/drivers/bt/hci_stub_drv.c")
endif()
# power save
list(APPEND priv_include "${host_dir}/drivers/power_save")
list(APPEND srcs "${host_dir}/drivers/power_save/power_save_drv.c")
# transport files
if(CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/drivers/transport/sdio/sdio_drv.c")
elseif(CONFIG_ESP_HOSTED_SPI_HD_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/drivers/transport/spi_hd/spi_hd_drv.c")
elseif(CONFIG_ESP_HOSTED_SPI_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/drivers/transport/spi/spi_drv.c")
elseif(CONFIG_ESP_HOSTED_UART_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/drivers/transport/uart/uart_drv.c")
endif()
# port files
list(APPEND priv_include "${host_dir}/port/esp/freertos/include")
list(APPEND srcs
"${host_dir}/port/esp/freertos/src/port_esp_hosted_host_init.c"
"${host_dir}/port/esp/freertos/src/port_esp_hosted_host_os.c"
#"${host_dir}/port/esp/freertos/src/port_esp_hosted_host_ota.c"
"${host_dir}/port/esp/freertos/src/port_esp_hosted_host_transport_defaults.c"
)
if(CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/port/esp/freertos/src/port_esp_hosted_host_sdio.c")
elseif(CONFIG_ESP_HOSTED_SPI_HD_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/port/esp/freertos/src/port_esp_hosted_host_spi_hd.c")
elseif(CONFIG_ESP_HOSTED_SPI_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/port/esp/freertos/src/port_esp_hosted_host_spi.c")
elseif(CONFIG_ESP_HOSTED_UART_HOST_INTERFACE)
list(APPEND srcs "${host_dir}/port/esp/freertos/src/port_esp_hosted_host_uart.c")
endif()
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES soc esp_event esp_netif esp_timer esp_wifi bt esp_http_client console wpa_supplicant esp_driver_spi esp_driver_gpio
REQUIRES esp_driver_sdmmc esp_driver_uart
INCLUDE_DIRS ${pub_include}
PRIV_INCLUDE_DIRS ${priv_include})
idf_component_set_property(${COMPONENT_NAME} WHOLE_ARCHIVE TRUE)
if(CONFIG_ESP_HOSTED_SDIO_HOST_INTERFACE)
idf_component_optional_requires(PRIVATE sdmmc)
endif()
# Required if using ESP-IDF without commit 6b6065de509b5de39e4655fd425bf96f43b365f7:
# fix(driver_spi): fix p4 cache auto writeback during spi(dma) rx
# if(CONFIG_IDF_TARGET_ESP32P4 AND (CONFIG_ESP_HOSTED_SPI_HOST_INTERFACE OR CONFIG_ESP_HOSTED_SPI_HD_HOST_INTERFACE))
# # used to workaround SPI transfer issue
# idf_component_optional_requires(PRIVATE esp_mm)
# endif()
idf_component_get_property(lwip lwip COMPONENT_LIB)
if(TARGET ${lwip})
# Use generator expressions to only apply to non-INTERFACE targets
get_target_property(lwip_type ${lwip} TYPE)
if(NOT lwip_type STREQUAL "INTERFACE_LIBRARY")
message(STATUS "********** Configuring LWIP for network split mode with custom hook **********")
target_include_directories(${lwip} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common")
target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"${CMAKE_CURRENT_SOURCE_DIR}/common/esp_hosted_lwip_src_port_hook.h\"")
endif()
endif()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,284 @@
# ESP-Hosted-MCU: Espressif SoCs as Communication Co-Processors
[![Component Registry](https://components.espressif.com/components/espressif/esp_hosted/badge.svg)](https://components.espressif.com/components/espressif/esp_hosted)
## 1 Introduction
ESP-Hosted-MCU is an open-source solution that allows you to use Espressif Chipsets and modules as a communication co-processor. This solution provides wireless connectivity (Wi-Fi and Bluetooth) to the host microprocessor or microcontroller, enabling it to communicate with other devices. Additionally, the user has complete control over the co-processor's resources.
This high-level block diagram shows ESP-Hosted's relationship with the host MCU and slave co-processor.
<img src="docs/images/ESP-Hosted-FG-MCU_design.svg" alt="ESP-Hosted">
For detailed design diagrams in Wi-Fi and Bluetooth, refer to the following design documents:
- [WiFi Design](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/wifi_design.md)
- [Bluetooth Design](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/bluetooth_design.md)
`esp-hosted-mcu` is dedicated for any host as MCU support. If you are interested in Linux as host, please refer to the [`esp-hosted`](https://github.com/espressif/esp-hosted) repository.
## 2 Architecture
##### Hosted Co-Processor
This is an ESP chip that provides Wi-Fi, Bluetooth, and other capabilities. It is also referred as `hosted-slave` interchangeably.
##### Host MCU
This can be any generic microcontroller (MCU). We demonstrate any ESP as host. Using port layer, any host can act as host MCU.
##### Communication
- Host extends the capabilities of the Hosted co-processor through Remote Procedure Calls (RPCs). The Host MCU sends these RPC commands to the Hosted co-processor using a reliable communication bus, like SPI, SDIO, or UART. The Hosted co-processor then handles the RPC and provides the requested functionality to the Host MCU.
- The data (network or Bluetooth) is packaged efficiently at the transport layer to minimize overhead and delays when passing between the Host and co-processor.
- This modular design allows any MCU to be used as the Host, and any ESP chip with Wi-Fi and/or Bluetooth to be used as the Hosted co-processor. The RPC calls can also be extended to provide any function required by the Host, as long as the co-processor can support it.
- The RPCs implemented are [listed in this document](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/implemented_rpcs.md), including the ESP-Hosted release version that implements the RPCs.
## 3 Solution Flexibility
- **Any MCU can be the host**
- You can evaluate ESP as an example host and then port ESP-Hosted to your desired MCU.
- **Any ESP chip can be the co-processor**
- Any Wi-Fi and/or Bluetooth capable ESP chipset can be chosen as co-processor
- Choose the co-processor device based on your product requirements. The [ESP Product Selector](https://www.espressif.com/en/products/socs) can help in this.
- **Flexible transport layer (SDIO, SPI, UART)**
- ESP-Hosted supports various communication interfaces between the host and the co-processor, allowing you to choose the most suitable one for your application.
- Any other new transport also could be added to the open source code
- **Complete control over co-processor's resources**
- The user is not limited to just using the co-processor for wireless connectivity. They have complete control over the co-processor's resources, allowing for a more flexible and powerful system.
- **Extensible RPC library**
- The Remote Procedure Call (RPC) used by ESP-Hosted can be extended to provide any function required by the Host, as long as the co-processor can support it. Currently, the essential [ESP-IDF](https://github.com/espressif/esp-idf) Wi-Fi functions have been implemented.
## 3.1 Features Supported by ESP-Hosted
See the [Features](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/features.md) document for features currently supported by ESP-Hosted.
## 4 Quick Demo with ESP32-P4-Function-EV-Board
Impatient to test? We've got you covered!
The [ESP32-P4-Function-EV-Board](https://www.espressif.com/en/products/socs/esp32-p4) can be used as a host MCU with an on-board [ESP32-C6](https://www.espressif.com/en/products/socs/esp32-c6) as co-processor, already connected via SDIO as transport.
Prerequisite: You need to have an ESP32-P4-Function-EV-Board`
> [!NOTE]
> If you have already set up ESP-IDF (version 5.3 or later), you can skip to [5 Source Code and Dependencies](#5-source-code-and-dependencies).
### 4.1 Set-Up ESP-IDF
- Windows
- Install and setup ESP-IDF on Windows as documented in the [Standard Setup of Toolchain for Windows](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/windows-setup.html).
- Use the ESP-IDF [Powershell Command Prompt](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/windows-setup.html#using-the-command-prompt) to move to expected
- Linux or MacOS
- bash
```bash
bash docs/setup_esp_idf__latest_stable__linux_macos.sh
```
- fish
```fish
fish docs/setup_esp_idf__latest_stable__linux_macos.fish
```
### 4.2 Set-Up P4 with C6
The host, ESP32-P4, lacks native Wi-Fi/Bluetooth support. Our [Quick Demo](docs/esp32_p4_function_ev_board.md) will help you run iperf over P4--SDIO--C6.
### 4.3 Don't Have ESP32-P4-Function-EV-Board?
No worries if you don't have an ESP32-P4. In fact, most users don't. You can choose and use any two ESP chipsets/SoCs/Modules/DevKits. DevKits are convenient to use as they have GPIO headers already in place. From these two ESP chipsets, one would act as host and another as slave/co-processor. However, as these are not connected directly, you would need to manually connect some transport, which is explained later in the section [`Detailed Setup`](#7-detailed-setup).
## 5 Source Code and Dependencies
### 5.1 ESP-Hosted-MCU Source Code
- ESP-Hosted-MCU code can be found at Espressif Registry Component [`esp_hosted` (ESP-Hosted)](https://components.espressif.com/components/espressif/esp_hosted) or GitHub repo at [`esp-hosted-mcu`](https://github.com/espressif/esp-hosted-mcu/)
- ESP-Hosted repo clone is **not** required if you have ESP as host.
- Reason: [ESP component manager](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/tools/idf-component-manager.html) automatically clones esp-hosted component while building.
- However, For non-ESP host development, you can clone the repo using command:
```bash
git clone --recurse-submodules --depth 1 https://github.com/espressif/esp-hosted-mcu.git
```
### 5.2 Dependencies
ESP-Hosted-MCU Solution is dependent on `ESP-IDF`, `esp_wifi_remote` and `protobuf-c`
###### ESP-IDF
- [`ESP-IDF`](https://github.com/espressif/esp-idf) is the development framework for Espressif SoCs supported on Windows, Linux and macOS
- ESP-Hosted-MCU solution is based on ESP-IDF as base software. ESP chipsets as host and slave always tried to design such a way that ESP-IDF components are re-used.
- Although, We totally understand, host MCUs in case of non-ESP chipset may not desire to be dependent on ESP-IDF. The port layer is written to avoid suc dependencies. Some crucial ESP-IDF components could also be just copy-pasted to fast-track the non-ESP host development.
###### Wi-Fi Remote
- [`esp_wifi_remote`](https://components.espressif.com/components/espressif/esp_wifi_remote) i.e. 'Wi-Fi Remote' is very thin interface made up of ESP-IDF Wi-Fi APIs with empty weak definitions. Real definitions for these APIs are provided by ESP-Hosted-MCU
- Wi-Fi Remote Code can be found at either [GitHub Repo](https://github.com/espressif/esp-wifi-remote/) or [Espressif Registry Component](https://components.espressif.com/components/espressif/esp_wifi_remote)
###### Protobuf
- [`protobuf-c`](https://github.com/protobuf-c/protobuf-c) is data serialization framework provided by Google. RPC messages communicated in host and slave are protobuf encoded.
- It helps to avoid manual serialization or endien-ness conversion.
- Provides Flexibility for users to port the ESP-Hosted-MCU RPC framework in any protobuf supported programming language
- Code is checked-out as submodule at `common/protobuf-c`
##### 5.2.1 How Dependencies Work Together (short explanation)
- RPC Request - Response
- Wi-Fi Remote is an API layer or interface that provides the standard ESP-IDF Wi-Fi calls to the application (`esp_wifi_init()`, etc.)
- Wi-Fi Remote forwards the Wi-Fi calls to ESP-Hosted, as ESP-Hosted 'implements' tha APIs provided by Wi-Fi Remote interface.
- ESP-Hosted host MCU creates RPC requests which are protobuf encoded and sends over the transport (SPI/SDIO etc) to the slave.
- Slave de-serialize the protobuf RPC request and response send back to host over transport, again with protobuf serialised.
- Responses received at transport returned to Wi-Fi Remote, which returns the reponses to the calling app at host
- To the app, it is as if it made a standard ESP-IDF Wi-Fi API call.
- RPC Event
- Asynchronous Wi-Fi events when subscribed, are sent by slave to host.
- These events terminate in standard ESP-IDF event loop on the host
- Please note, Only RPC i.e. control packets are serialised. Data Packets are never serialised as they do not need endien conversion.
## 6 Decide the communication bus in between host and slave
The communication bus is required to be setup correctly between host and slave.
We refer this as `transport medium` or simply `transport`.
ESP-Hosted-MCU supports SPI/SDIO/UART transports. User can choose which transport to use. Choosing specific transport depends on factors: high performance, easy and quick to test, number of GPIOs used, or simply co-processor preference
Below is chart for the transport medium comparison.
Legends:
- `FD` : Full duplex communication
- `HD` : Half duplex communication
- `BT` : Bluetooth
- `+2` in column `Num of GPIOs`
- There are two GPIOs additional applicable for all the transports
- (1) Co-Processor reset: Host needs one additional pin to connect to `RST`/`EN` pin of co-processor, to reset on bootup
- (2) Ground: Grounds of both chipsets need to be connected.
- If you use jumper cable connections, connect as many grounds as possible in between two boards for better noise cancellation.
- `Any_Slave`
- Co-processor suppored: ESP32, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-S2, ESP32-S3
- Classic ESP32 supports 'Classic BT', 'BLE 4.2' & 'BTDM'
- Rest all chipsets support BLE only. BLE version supported is 5.0+. Exact bluetooth versions could be refered from [ESP Product Selector Page](https://products.espressif.com/#/product-selector)
- `Dedicated platforms`
- Bluetooth uses dedicated platform, UART and Wi-Fi uses any other base transport
- In other platforms, Bluetooth and Wi-Fi re-use same platform and hence use less GPIOs and less complicated
- This transport combination allows Bluetooth to use dedicated uart transportt with additional 2 or 4 depending on hardware flow control.
- (S) : Shield box reading
- (O) : Over the air reading
- TBD : To be determined
- iperf : iperf2 with test resukts in mbps
> [!NOTE]
>
> For the shield box readings maked with (S), full network set up explained in [Shield Box Test Setup](shield-box-test-setup.md)
**Host can be any ESP chipset or any non-ESP MCU.**
###### Hosted Transports table
| Transport | Type | Num of GPIOs | Setup with | Co-processor supported | Host Tx iperf | Host Rx iperf | Remarks |
|:---------------:|:-----:|:------------:|:----------------:|:--------------:|:------------:|:-----------:|:--------------------------:|
| Standard SPI | FD | 6 | jumper or PCB | Any_Slave | udp: 24 tcp: 22 | udp: 25 tcp: 22| Simplest solution for quick test |
| Dual SPI | HD | 5 | jumper or PCB | Any_Slave [1] | udp: 32 tcp: 26 (O) | udp: 33 tcp: 25 (O) | Better throughput, but half duplex |
| Quad SPI | HD | 7 | PCB only | Any_Slave [1] | udp: 41 tcp: 29 (O) | udp: 42 tcp: 28 (O) | Due to signal integrity, PCB is mandatory |
| SDIO 1-Bit | HD | 4 | jumper or PCB | ESP32, ESP32-C6, ESP32-C5, ESP32-C61 | TBD | TBD | Stepping stone for PCB based SDIO 4-bit |
| SDIO 4-Bit | HD | 6 | PCB only | ESP32, ESP32-C6, ESP32-C5, ESP32-C61 | udp: 79.5 tcp: 53.4 (S) | udp: 68.1 tcp: 44 (S) | Highest performance |
| Only BT over UART | FD | 2 or 4 | jumper or PCB | Any_Slave | NA | NA | Dedicated Bluetooth over UART pins |
| UART | FD | 2 | jumper or PCB | Any_Slave | udp: 0.68 tcp: 0.67 (O) | udp: 0.68 tcp: 0.60 (O) | UART dedicated for BT & Wi-Fi [2] |
| Dedicated platforms | FD | Extra 2 or 4 | jumper or PCB | Any_Slave | NA | NA | UART dedicated for BT & Wi-Fi on any other transport |
> [!NOTE]
> - [1] Dual/Quad SPI is not supported on ESP32
> - [2] UART is suitable only for low throughput environments. Throughput was obtained with a baud rate of 921600. On the ESP32-P4 + C6 development board, a baud rate of 4 Mbits/s can be achieved, giving TCP/UDP throughput of around 3.3 MBits/s.
With jumper cables, 'Standard SPI' and 'Dual SPI' solutions are easiest to evaluate, without much of hardware dependencies. SDIO 1-Bit can be tested with jumper cables, but it needs some additional hardware config, such as installation of external pull-up registers.
In case case of dedicated platforms, Blutooth uses standard HCI over UART. In rest of cases, Bluetooth and Wi-Fi uses same transport and hence less GPIOs and less complicated. In shared mode, bluetooth runs as Hosted HCI (multiplexed mode)
## 7 ESP-Hosted-MCU Header
### 7.1 ESP Hosted header
Host and slave always populate below header at the start of every frame, irrespective of actual or dummy data in payload.
| Field | Type | Bits | Mandatory? | Description |
|----------------|----------|------|------------|-----------------------------------------------------------------------------|
| if_type | uint8_t | 4 | M | Interface type |
| if_num | uint8_t | 4 | M | Interface number |
| flags | uint8_t | 8 | M | Flags for additional information |
| len | uint16_t | 16 | M | Length of the payload |
| offset | uint16_t | 16 | M | Offset for the payload |
| checksum | uint16_t | 16 | M | Checksum for error detection (0 if checksum disabled) |
| seq_num | uint16_t | 16 | O | Sequence number for tracking packets (Useful in debugging) |
| throttle_cmd | uint8_t | 0 or 2 | O | Flow control command |
| reserved2 | uint8_t | 6 or 8 | M | Reserved bits |
| reserved3 | uint8_t | 8 | M | Reserved byte (union field) |
| hci\_pkt\_type or priv\_pkt\_type | uint8_t | 8 | M | Packet type for HCI interface (union field) |
### 7.2 Interface Types
Start of header states which type of frame is being carried.
| Interface Type | Value | Description |
|----------------------|-------|--------------------------------------------------|
| ESP\_INVALID\_IF | 0 | Invalid interface |
| ESP\_STA\_IF | 1 | Station frame |
| ESP\_AP\_IF | 2 | SoftAP frame |
| ESP\_SERIAL\_IF | 3 | Control frame |
| ESP\_HCI\_IF | 4 | Bluetooth Hosted HCI frame |
| ESP\_PRIV\_IF | 5 | Private communication between slave and host |
| ESP\_TEST\_IF | 6 | Transport throughput test |
| ESP\_ETH\_IF | 7 | Invalid |
| ESP\_MAX\_IF | 8 | type mentioned in dummy or empty frame |
## 8 Detailed Setup
Once you decided the transport to use, this section should guide how to set this transport, with hardware connections, configurations and verification. Users can evaluate one transport first and then move to other.
> [!IMPORTANT]
>
> [Design Considerations](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/design_consideration.md) that could be referred to, before you stick to any transport option. Referring to these consideration would help to get you faster to solution, make your design stable and less error-prone.
Irrespective of transport chosen, following steps are needed, which are step-wise explained in each transport.
1. Set-up the hosted-transport
2. Slave Flashing
- Slave project creation
- Slave configuration
- Slave flashing
- Slave logs
3. Host flashing
- Host project integration with ESP-IDF example
- Host configuration
- Host flashing
- Host logs
- [**Standard SPI (Full duplex)**](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/spi_full_duplex.md)
- [**SPI - Dual / Quad Half Duplex**](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/spi_half_duplex.md)
- [**SDIO (1-Bit / 4-Bit)**](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/sdio.md)
- [**UART for Wi-Fi and Bluetooth**](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/uart.md)
## 9 Examples
Check [examples](https://github.com/espressif/esp-hosted-mcu/tree/main/examples) directory for sample applications using ESP-Hosted.
- `examples/host_bluedroid_ble_compatibility_test`
- host BlueDroid Bluetooth example to test the Bluetooth compatibility and mobile phones
- `examples/host_bluedroid_bt_hid_mouse_device`
- host BlueDroid Bluetooth example to show how to implement a Bluetooth HID device using the APIs provided by Classic Bluetooth HID profile
- `examples/host_bluedroid_host_only`
- host BlueDroid Bluetooth example Bluetooth Host using ESP-Hosted as HCI IO to the BT Controller
- `examples/host_nimble_bleprph_host_only_vhci`
- host NimBLE Bluetooth example without needing extra GPIOs for HCI transport
## 10 Troubleshooting
If you encounter issues with using ESP-Hosted, see the following guide:
- [Troubleshooting Guide](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/troubleshooting.md)
- [Migration Guide](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/migration_guide.md)
- if you are upgrading to ESP-Hosted version V2.5.2 (or later) from an earlier version, there has been a change in the operation of the Bluetooth Controller on the co-processor. See [Migrating to V2.5.2](https://github.com/espressif/esp-hosted-mcu/blob/main/docs/migration_guide.md#migrating-to-v252) in the Migration Guide for more information.
## 11 References
- [ESP Product Selector Page](https://products.espressif.com)
- [ESP-IDF Get Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started)
- [ESP-IDF Wi-Fi API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html)
- [ESP-IDF Iperf Example](https://github.com/espressif/esp-idf/tree/master/examples/wifi/iperf)
- [ESP-IDF NimBLE](https://github.com/espressif/esp-nimble)
- [ESP Component Registry](https://components.espressif.com)
- [Registry Component: esp\_wifi\_remote](https://components.espressif.com/components/espressif/esp_wifi_remote)
- [Registry Component: esp\_hosted](https://components.espressif.com/components/espressif/esp_hosted)

View File

@@ -0,0 +1,41 @@
// Copyright 2025 Espressif Systems (Shanghai) PTE LTD
/* SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0 */
#ifndef __ESP_HOSTED_HEADER__H
#define __ESP_HOSTED_HEADER__H
/* Add packet number to debug any drops or out-of-seq packets */
//#define ESP_PKT_NUM_DEBUG 1
struct esp_payload_header {
uint8_t if_type:4;
uint8_t if_num:4;
uint8_t flags;
uint16_t len;
uint16_t offset;
uint16_t checksum;
uint16_t seq_num;
uint8_t throttle_cmd:2;
uint8_t reserved2:6;
#ifdef ESP_PKT_NUM_DEBUG
uint16_t pkt_num;
#endif
/* Position of union field has to always be last,
* this is required for hci_pkt_type */
union {
uint8_t reserved3;
uint8_t hci_pkt_type; /* Packet type for HCI interface */
uint8_t priv_pkt_type; /* Packet type for priv interface */
};
/* Do no add anything here */
} __attribute__((packed));
/* ESP Payload Header Flags */
#define MORE_FRAGMENT (1 << 0)
#define FLAG_WAKEUP_PKT (1 << 1)
#define FLAG_POWER_SAVE_STARTED (1 << 2)
#define FLAG_POWER_SAVE_STOPPED (1 << 3)
#define H_ESP_PAYLOAD_HEADER_OFFSET sizeof(struct esp_payload_header)
#endif

View File

@@ -0,0 +1,30 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_HOSTED_INTERFACE_H__
#define __ESP_HOSTED_INTERFACE_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ESP_INVALID_IF,
ESP_STA_IF,
ESP_AP_IF,
ESP_SERIAL_IF,
ESP_HCI_IF,
ESP_PRIV_IF,
ESP_TEST_IF,
ESP_ETH_IF,
ESP_MAX_IF,
} esp_hosted_if_type_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#ifndef __ESP_HOSTED_LWIP_SRC_PORT_HOOK_H__
#define __ESP_HOSTED_LWIP_SRC_PORT_HOOK_H__
#include "sdkconfig.h"
#if defined(CONFIG_ESP_HOSTED_NETWORK_SPLIT_ENABLED)
#include "lwip/opt.h"
/* ----------------------------------Slave (local) Port Config---------------------------------------- */
/* If configured, Any new UDP socket would automatically bind as local port within this specified UDP port range.
* Please note, Reserved ports (generally <1024) like DHCP, etc would still work as they generally are hardcoded
*/
#define ENSURE_PORT_RANGE(port, START, END) \
(((port) >= (START) && (port) <= (END)) ? \
(port) : \
(((port) % ((END) - (START) + 1)) + (START)))
#ifdef CONFIG_LWIP_TCP_LOCAL_PORT_RANGE_START
#define TCP_LOCAL_PORT_RANGE_START CONFIG_LWIP_TCP_LOCAL_PORT_RANGE_START
#define TCP_LOCAL_PORT_RANGE_END CONFIG_LWIP_TCP_LOCAL_PORT_RANGE_END
#define TCP_ENSURE_LOCAL_PORT_RANGE(port) ENSURE_PORT_RANGE(port, TCP_LOCAL_PORT_RANGE_START, TCP_LOCAL_PORT_RANGE_END)
#if CONFIG_LWIP_TCP_LOCAL_PORT_RANGE_END == 0xffff
#define IS_LOCAL_TCP_PORT(port) (port>=TCP_LOCAL_PORT_RANGE_START)
#else
#define IS_LOCAL_TCP_PORT(port) (port>=TCP_LOCAL_PORT_RANGE_START && (port<=CONFIG_LWIP_TCP_LOCAL_PORT_RANGE_END))
#endif
#endif
#ifdef CONFIG_LWIP_TCP_REMOTE_PORT_RANGE_START
#define TCP_REMOTE_PORT_RANGE_START CONFIG_LWIP_TCP_REMOTE_PORT_RANGE_START
#define TCP_REMOTE_PORT_RANGE_END CONFIG_LWIP_TCP_REMOTE_PORT_RANGE_END
#define TCP_ENSURE_REMOTE_PORT_RANGE(port) ENSURE_PORT_RANGE(port, TCP_REMOTE_PORT_RANGE_START, TCP_REMOTE_PORT_RANGE_END)
#if CONFIG_LWIP_TCP_REMOTE_PORT_RANGE_END == 0xffff
#define IS_REMOTE_TCP_PORT(port) (port>=TCP_REMOTE_PORT_RANGE_START)
#else
#define IS_REMOTE_TCP_PORT(port) (port>=TCP_REMOTE_PORT_RANGE_START && (port<=CONFIG_LWIP_TCP_REMOTE_PORT_RANGE_END))
#endif
#endif
#ifdef CONFIG_LWIP_UDP_LOCAL_PORT_RANGE_START
#define UDP_LOCAL_PORT_RANGE_START CONFIG_LWIP_UDP_LOCAL_PORT_RANGE_START
#define UDP_LOCAL_PORT_RANGE_END CONFIG_LWIP_UDP_LOCAL_PORT_RANGE_END
#define UDP_ENSURE_LOCAL_PORT_RANGE(port) ENSURE_PORT_RANGE(port, UDP_LOCAL_PORT_RANGE_START, UDP_LOCAL_PORT_RANGE_END)
#if CONFIG_LWIP_UDP_LOCAL_PORT_RANGE_END == 0xffff
#define IS_LOCAL_UDP_PORT(port) (port>=UDP_LOCAL_PORT_RANGE_START)
#else
#define IS_LOCAL_UDP_PORT(port) (port>=UDP_LOCAL_PORT_RANGE_START && (port<=CONFIG_LWIP_UDP_LOCAL_PORT_RANGE_END))
#endif
#define DNS_PORT_ALLOWED(port) IS_LOCAL_UDP_PORT(port)
#endif
#ifdef CONFIG_LWIP_UDP_REMOTE_PORT_RANGE_START
#define UDP_REMOTE_PORT_RANGE_START CONFIG_LWIP_UDP_REMOTE_PORT_RANGE_START
#define UDP_REMOTE_PORT_RANGE_END CONFIG_LWIP_UDP_REMOTE_PORT_RANGE_END
#define UDP_ENSURE_REMOTE_PORT_RANGE(port) ENSURE_PORT_RANGE(port, UDP_REMOTE_PORT_RANGE_START, UDP_REMOTE_PORT_RANGE_END)
#if CONFIG_LWIP_UDP_REMOTE_PORT_RANGE_END == 0xffff
#define IS_REMOTE_UDP_PORT(port) (port>=UDP_REMOTE_PORT_RANGE_START)
#else
#define IS_REMOTE_UDP_PORT(port) (port>=UDP_REMOTE_PORT_RANGE_START && (port<=CONFIG_LWIP_UDP_REMOTE_PORT_RANGE_END))
#endif
#endif
#endif
#endif /* __ESP_HOSTED_LWIP_SOURCE_PORT_BINDING_HOOK_H__ */

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef __ESP_HOSTED_LOG_H
#define __ESP_HOSTED_LOG_H
#include "esp_log.h"
#define ESP_PRIV_HEXDUMP(tag1, tag2, buff, buf_len, display_len, curr_level) \
if ( LOG_LOCAL_LEVEL >= curr_level) { \
int len_to_print = 0; \
len_to_print = display_len<buf_len? display_len: buf_len; \
ESP_LOG_LEVEL_LOCAL(curr_level, tag1, "%s: buf_len[%d], print_len[%d]", \
tag2, (int)buf_len, (int)len_to_print); \
ESP_LOG_BUFFER_HEXDUMP(tag2, buff, len_to_print, curr_level); \
}
#define ESP_HEXLOGE(tag2, buff, buf_len, display_len) ESP_PRIV_HEXDUMP(TAG, tag2, buff, buf_len, display_len, ESP_LOG_ERROR)
#define ESP_HEXLOGW(tag2, buff, buf_len, display_len) ESP_PRIV_HEXDUMP(TAG, tag2, buff, buf_len, display_len, ESP_LOG_WARN)
#define ESP_HEXLOGI(tag2, buff, buf_len, display_len) ESP_PRIV_HEXDUMP(TAG, tag2, buff, buf_len, display_len, ESP_LOG_INFO)
#define ESP_HEXLOGD(tag2, buff, buf_len, display_len) ESP_PRIV_HEXDUMP(TAG, tag2, buff, buf_len, display_len, ESP_LOG_DEBUG)
#define ESP_HEXLOGV(tag2, buff, buf_len, display_len) ESP_PRIV_HEXDUMP(TAG, tag2, buff, buf_len, display_len, ESP_LOG_VERBOSE)
#endif

View File

@@ -0,0 +1,53 @@
# About Proto Files
## Protobuf Submodule
[protobuf-c](https://github.com/protobuf-c/protobuf-c) is open source code used as submodule in ESP-Hosted-FG in directory `../protobuf-c/`
If this directory is empty, please run
```sh
$ cd esp-hosted
$ git submodule update --init --recursive
```
## Files
- `esp_hosted_rpc.proto`
- This is Ready-To-Use protobuf file which has messages for Request / Response / Events to communicate between Host and ESP
- User can add his own message field in `.proto` file and generate respective C files using 'protoc'
- `esp_hosted_rpc.pb-c.c` & `esp_hosted_rpc.pb-c.h`
- Ready-To-Use Source Generated files using `esp_hosted_rpc.proto`
- These files also cached which was generated with current `esp_hosted_rpc.proto` file for easy use (No need to generate again)
- If any addition or modifications `esp_hosted_rpc.proto` done, these files need to be re-generated
## Generate esp_hosted_rpc.pb-c.c & esp_hosted_rpc.pb-c.h
If you want to add or modify existing set of RPC procedures supported, you need to modify `esp_hosted_rpc.proto` as needed and build it to generate new set of `esp_hosted_rpc.pb-c.c` & `esp_hosted_rpc.pb-c.h`.
For this, third party software for protobuf C compiler is needed to be installed
- Debian/Ubuntu
- sudo apt install protobuf-c-compiler
- Mac OS
- brew install protobuf
- Windows
- check https://github.com/protobuf-c/protobuf-c
`protoc-c` command should be available once installed.
This software might only be needed on development environment, Once esp_hosted_rpc.pb-c.c & esp_hosted_rpc.pb-c.h files are generated, could also be uninstalled.
##### Steps to generate
```sh
$ cd <path/to/esp_hosted_fg>/common/proto
$ protoc-c esp_hosted_rpc.proto --c_out=.
```
## Add new RPC message
To send an new RPC request/response
<TBD>
1. Add C function in `host/host_common/commands.c`
2. Create python binding in `host/linux/host_control/python_support/commands_map_py_to_c.py` and its python function in `host/linux/host_control/python_support/commands_lib.py`.
3. Add ESP side C function in `esp/esp_driver/network_adapter/main/slave_commands.c`, respective to python function, to handle added message field.
User can test added functionality using `host/linux/host_control/python_support/test.py`.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
#!/bin/bash -e
# from git-sh-setup.sh
require_clean_work_tree () {
git rev-parse --verify HEAD >/dev/null || exit 1
git update-index -q --ignore-submodules --refresh
err=0
if ! git diff-files --quiet --ignore-submodules
then
echo >&2 "Cannot $0: You have unstaged changes."
err=1
fi
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
then
if [ $err = 0 ]
then
echo >&2 "Cannot $0: Your index contains uncommitted changes."
else
echo >&2 "Additionally, your index contains uncommitted changes."
fi
err=1
fi
if [ $err = 1 ]
then
test -n "$2" && echo >&2 "$2"
exit 1
fi
}
require_clean_work_tree
if ! which doxygen >/dev/null; then
echo "Error: doxygen is required"
exit 1
fi
DOXYGEN_VERSION="$(doxygen --version)"
DOC_BRANCH="gh-pages"
ORIG_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
ORIG_COMMIT="$(git describe --match=NeVeRmAtCh --always --abbrev=40 --dirty)"
TOP="$(pwd)"
export GIT_DIR="$TOP/.git"
TMPDIR="$(mktemp --tmpdir=$TOP -d)"
HTMLDIR="$TMPDIR/_build/html"
INDEX_FILE="$GIT_DIR/index.${DOC_BRANCH}"
rm -f "$INDEX_FILE"
trap "{ cd $TOP; git checkout --force ${ORIG_BRANCH}; rm -f $INDEX_FILE; rm -rf $TMPDIR; }" EXIT
cd "$TMPDIR"
git reset --hard HEAD
./autogen.sh
mkdir _build
cd _build
../configure
make html
if ! git checkout "${DOC_BRANCH}"; then
git checkout --orphan "${DOC_BRANCH}"
fi
touch "$HTMLDIR/.nojekyll"
GIT_INDEX_FILE="$INDEX_FILE" GIT_WORK_TREE="$HTMLDIR" \
git add --no-ignore-removal .
GIT_INDEX_FILE="$INDEX_FILE" GIT_WORK_TREE="$HTMLDIR" \
git commit -m "Rebuild html documentation from commit ${ORIG_COMMIT} using Doxygen ${DOXYGEN_VERSION}"

View File

@@ -0,0 +1,43 @@
*~
.*swp
*.la
*.gcda
*.gcno
*.lo
*.log
*.o
*.tar.gz
*.trs
.deps/
.dirstamp
.libs/
/Doxyfile
/Makefile
/Makefile.in
/aclocal.m4
/autom4te.cache
/build-aux
/config.*
/configure
/doxygen-doc
/html
/libtool
/protobuf-c-*-coverage.info
/protobuf-c-*-coverage/
/stamp-h1
/stamp-html
/test-suite.log
TAGS
protobuf-c/libprotobuf-c.pc
protoc-c/protoc-c
protoc-c/protoc-gen-c
t/generated-code/test-generated-code
t/generated-code2/cxx-generate-packed-data
t/generated-code2/test-full-cxx-output.inc
t/generated-code2/test-generated-code2
t/generated-code3/test-generated-code3
t/version/version
*.pb-c.c
*.pb-c.h
*.pb.cc
*.pb.h

View File

@@ -0,0 +1,5 @@
## Contributing
The most recently released `protobuf-c` version is kept on the `master` branch, while the `next` branch is used for commits targeted at the next release. Please base patches and pull requests against the `next` branch. __Do not open pull requests against master!__
Copyright to all contributions are retained by the original author, but must be licensed under the terms of the [BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause) license.

View File

@@ -0,0 +1,564 @@
protobuf-c (1.4.1)
[ Robert Edmonds ]
* Release 1.4.1
[ Todd C. Miller ]
* Only shift unsigned values to avoid implementation-specific behavior
(#506, #508).
* Fix regression with zero-length messages introduced in protobuf-c PR 500.
* Fix a clang analyzer 14 warning about a possible NULL deref (#512, #514).
[ steed717 ]
* Fix unsigned integer overflow (#499, #513).
protobuf-c (1.4.0)
[ Robert Edmonds ]
* Release 1.4.0.
[ Ilya Lipnitsky ]
* c_message.cc: Resolve name conflict between certain enums and oneofs
(#427).
* protobuf-c.h: Fix Windows DLL export issue with the
protobuf_c_empty_string symbol (#428).
* Standardize pkg-config for use by autotools and cmake, fix cmake tests
(#425).
* protobuf-c.c: Cast %lu args to unsigned long int (#429).
* protoc-c: Remove leading underscores from structs (#430).
* protoc-c: Fix shared lib build on windows, migrate from Travis CI to
GitHub Actions (#459).
* protobuf-c: Don't use ProtobufCWireType internally (#463).
* protoc-c: Add custom options support (#466).
* protobuf-c.c: Fix packed repeated bool parsing (#467).
[ Markus Engel ]
* Pack nested messages inline (#431).
[ Daniel Axtens ]
* Travis CI: Test on other platforms (#438).
[ Adam Cozzette ]
* Update the generator to fully qualify std::string (#443).
[ Piotr Pietraszkiewicz ]
* Install MSVC debug symbols alongside the protobuf-c.lib file (#456).
[ ihsinme ]
* Fix invalid unsigned arithmetic (#455).
[ Wolfram Rösler ]
* Avoid "unused function parameter" compiler warning (#453).
protobuf-c (1.3.3)
[ Robert Edmonds ]
* Release 1.3.3.
* Fix build failure on protobuf 2.x (#398).
[ msshapira ]
* CMake: Fix support for MSVC static build (#350).
[ Adam Cozzette ]
* Fix some test assertions in test-generated-code2.c (#392).
[ Ilya Lipnitskiy ]
* protobuf-c.c: Make zigzag encoding more compact (#400).
[ Markus Engel ]
* CMake: Fix endianness check.
protobuf-c (1.3.2)
[ Robert Edmonds ]
* Release 1.3.2.
* Use protobuf 3.7.1 in the Travis-CI environment (#368).
* Fix test suite build failure on newer versions of protobuf (#369).
[ Ilya Lipnitskiy ]
* Fix proto3 repeated scalar field default packing behavior (#330, #377).
[ Adam Cozzette ]
* Fix out-of-bounds read in scan_length_prefixed_data() (#375, #376).
[ Jurriaan Bremer ]
* Fix -Wdeclaration-after-statement warning in parse_oneof_member() (#360).
[ Hayri Ugur Koltuk ]
* Fix SIGSEGV in protobuf_c_message_check() on messages with unpopulated
oneof members (#358).
[ Italo Guerrieri ]
* Do not allow tag values of 0 in protobuf messages, as these are not
allowed by proto2 or proto3 (#299).
protobuf-c (1.3.1)
[ Robert Edmonds ]
* Release 1.3.1.
* Restore protobuf-2.x compatibility (#284, #285).
* Use xenial and protobuf 3.6.1 in the Travis-CI environment (#332).
* Convert uses of protobuf's scoped_ptr.h to C++11 std::unique_ptr, needed
to compile against protobuf 3.6.1 (#320, #333).
* Use AX_CXX_COMPILE_STDCXX macro to enable C++11 support in old compilers
(#312, #317, #327, #334).
[ Fredrik Gustafsson ]
* Add std:: to some types (#294, #305, #309).
[ Sam Collinson ]
* Check the return value of int_range_lookup before using as an array index;
it can return -1 (#315).
[ Matthias Dittrich ]
* Fix compilation on mingw by using explicit protoc --plugin=NAME=PATH syntax
in Makefile.am (#289, #290).
protobuf-c (1.3.0)
[ Robert Edmonds ]
* Release 1.3.0.
* Add test case for the issue in #220 (#254).
* Fix issue #251, "Bad enums with multiple oneofs" (#256).
* Add warning flags to my_CFLAGS (#257).
* Fix namespace errors when compiled with latest protobuf (#280).
* Bump minimum required header version for proto3 syntax (#282).
[ Paolo Borelli ]
* Turn the compiler into a protoc plugin (#206). This allows the protobuf-c
compiler to be invoked as "protoc --c_out=...". For backwards
compatibility, we still ship a protoc-c command, but it's a symlink to the
protoc-gen-c binary.
* proto3 support (#228).
* Remove leftover FIXME comment (#258).
* Fix proto3 "is zeroish" evaluation (#264).
* Small cleanup in oneof handling (#265).
* Rework is_zeroish one more time (#267).
* proto3: make strings default to "" instead of NULL (#274).
[ Tomek Wasilczyk ]
* Fix -Wsign-compare warnings (#213).
* Fix ISO C90 -Wdeclaration-after-statement warnings (#214).
* Fix bigendian -Wunused-label warning (#215).
[ Ilya Lipnitsky ]
* protoc-c/c_message.cc: Force int size on oneof enums (#221). Fixes wrong
enum generation and handling for onceof cases (#220).
[ Adnan ]
* Fix cmake build if built as part of an external project (#231).
[ Gregory Detal ]
* Remove .pb.{cc,h} in distdir instead of top_distdir in order to prevent
removing files from other projects when protobuf-c is included as an
autotools subproject (#232).
[ Ben Farnham ]
* Relax autoconf constraint from v2.64 to v2.63 so that it works on older
Linux distros (#233).
[ Thomas Köckerbauer ]
* rm argument fix for Solaris (#234).
* Add 'const' qualifier to 'init_value' variable in generated files (#236).
[ Richard Kettlewell ]
* Document and extend the effect of passing NULL to ..._free_unpacked
functions (#255).
[ Alex Milich ]
* CMake: Workaround for static builds that use MSVC (#243).
[ Josh Junon ]
* CMake: Allow protobuf-c to be included via include_subdirectory (#245).
[ Alexei Kasatkin ]
* CMake: Windows fixes (#266).
protobuf-c (1.2.1)
[ Robert Edmonds ]
* Release 1.2.1.
[ Paolo Borelli ]
* protoc-c: Generate code that uses the universal zero initializer {0} when
initializing a oneof union (#187, #205).
protobuf-c (1.2.0)
[ Robert Edmonds ]
* Release 1.2.0.
[ Ilya Lipnitsky ]
* Implement the "optimize_for = CODE_SIZE" option (#183).
* Eliminate undefined behavior in zigzag functions (#198).
* Pack negative enum values correctly (#199).
[ Peter Leschev ]
* Fix protobuf_c_message_get_packed_size() on 16-bit systems (#196, #197).
[ Diego Elio Pettenò ]
* Update link to Autotools Mythbuster to canonical site (#201).
[ Zex Li ]
* Skip test suite when cross-compiling (#184).
protobuf-c (1.1.1)
[ Robert Edmonds ]
* Release 1.1.1.
* Use protobuf 2.6.1 in the Travis-CI environment.
[ Ilya Lipnitskiy ]
* Munge C block comment delimiters in protobuf comments, preventing syntax
errors in generated header files (Issue #180, #185).
* Add static qualifier to ProtobufCEnumValue and ProtobufCEnumValueIndex
variables in generated output.
[ Oleg Efimov ]
* Fix -Wpointer-sign compiler diagnostics in the test suite.
* Check for NULL pointers in protobuf_c_message_free_unpacked()
(Issue #177).
* Exclude protoc-c and downloaded protobuf sources from Coveralls report.
[ Andrey Myznikov ]
* Fix incorrect 'short_name' field values in ProtobufCServiceDescriptor
variables in generated output.
protobuf-c (1.1.0)
[ Robert Edmonds ]
* Release 1.1.0.
[ Ilya Lipnitskiy ]
* Fix a bug when merging optional byte fields.
* Documentation updates.
* Implement oneof support (Issue #174). Protobuf 2.6.0 or newer is now
required to build protobuf-c.
* Print leading comments for enum, message, and field definitions into
generated header files (Issue #175).
protobuf-c (1.0.2)
[ Robert Edmonds ]
* Release 1.0.2.
[ Ilya Lipnitskiy ]
* Fix a build failure with Protobuf 2.6.0 related to aliased enum constants
(Issue #163).
* Protobuf 2.5.0 or newer is now required to build protobuf-c (Issue #166).
This is due to the fix for #163.
[ Alexei Kasatkin ]
* Eliminate void pointer arithmetic (Issue #167).
* Always define PROTOBUF_C__DEPRECATED, even on compilers that are not GCC
(Issue #167).
* Work around the lack of the 'inline' keyword in Microsoft compilers
(Issue #167).
* Add a CMakeLists.txt file as a fallback build system for Windows
(Issue #168).
[ Natanael Copa ]
* Fix a build failure in the test suite that occurred with a parallel make
running on a system with a large number of CPUs (Issue #156, #169).
protobuf-c (1.0.1)
[ Robert Edmonds ]
* Explicitly set the .data field of ProtobufCBinaryData's to NULL when
unpacking a zero length byte string (Issue #157).
protobuf-c (1.0.0)
[ Andrei Nigmatulin ]
* Append "u", "ull", and "ll" integer literal suffixes for uint32, uint64,
and int64 default values in generated code, in order to avoid "integer
constant is so large that it is unsigned" compiler warnings.
(Issue #136.)
* Revert the problematic hash-based required field detection.
(Related to Issue #60, #79, #137.)
* Replace the 'packed' member of ProtobufCFieldDescriptor with a 'flags'
word. Define flags for packed and deprecated fields. (Issue #138.)
[ Dave Benson ]
* Treat a "length-prefixed" wire-type message for a repeated field as
packed-repeated whenever it makes sense (for all types other than
messages, strings, and bytes).
* Switch to New BSD license.
* Add protobuf_c_message_check().
* Compile error in packing 64-bit versions on some platforms
(srobbins99: Issue #68 Comment 1).
* Fix for memory error if the required-field check fails. See Issue #63
for demo (w/ nice test case by dror.harari).
* Add PROTOBUF_C_{MAJOR,MINOR} for compile-time checks and
protobuf_c_{major,minor} for checks about the running library
(Issue #53).
* Use a small constant-size hash-table instead of alloca() for detecting
required fields, and it also prevents us from using too much stack, etc.
(Related to Issue #60, #79).
* Add a macro to ensure enums are the size of ints (Issue #69).
[ Ilya Lipnitskiy ]
* Travis-CI integration.
* Add source .proto filename to generated files.
* Add protobuf-c version to protoc-c --version output (Issue #52).
* For embedded submessage fields, merge multiple instances of the same
field, per the protobuf documentation (Issue #91).
* Don't print unpack errors by default.
* Optionally allow running the test suite under valgrind with ./configure
--enable-valgrind-tests. (Based on valgrind-tests.m4 from gnulib.)
[ Kevin Lyda ]
* Autoconf portability fixes.
* Add doxygen detection and make targets to the build system.
* Doxygen documentation for the libprotobuf-c public API (Issue #132).
[ Nick Galbreath ]
* Prevent possible overflow on 64-bit systems (Issue #106).
[ Robert Edmonds ]
* Remove CMake (Issue #87).
* Modernize the build system.
- Don't generate any diagnostics when building the build system with
modern autotools (Issue #89).
- Use the PKG_CHECK_MODULES macro to locate protobuf.
- Use the AC_C_BIGENDIAN macro to detect endianness, rather than custom
code.
- Use the automake silent-rules option so the build output is actually
readable.
- Generate our own pkg-config .pc files.
* Reorganize the source tree. This affects the public protobuf-c header
path, which is now <protobuf-c/protobuf-c.h>. A compatibility symlink from
<google/protobuf-c/> to <protobuf-c/> has been installed so that existing
code will continue to compile. New code should at some point begin using
the new include path, i.e., "#include <protobuf-c/protobuf-c.h>" rather
than "#include <google/protobuf-c/protobuf-c.h>".
* The RPC code has been split out into a separate project, protobuf-c-rpc.
* Fix a potential use of an unitialized value in protobuf_c_message_unpack()
and several memory leaks in protoc-c, discovered by a commercial static code
analysis tool.
* Bump the libprotobuf-c SONAME.
* Begin versioning the library's symbols. (Based on ld-version-script.m4
from gnulib.)
* Preserve case in enum value names generated by protoc-c (Issue #129).
Reported by Oleg Efimov.
* Add library functions protobuf_c_version() and protobuf_c_version_string()
for retrieving the version of the compiled library, and header macros
PROTOBUF_C_VERSION and PROTOBUF_C_VERSION_STRING for retrieving the
version of the header file. This replaces the interfaces for retrieving
the protobuf-c version numbers in Issue #53.
* Add a version guard that ensures that the output of protoc-c is only
compiled against a protobuf-c header file from the exact same protobuf-c
release.
* Add a --enable-code-coverage option to configure, which enables a
"make check-code-coverage" build target. This generates a code coverage
report and requires the lcov tool to be installed.
* Remove the old DocBook documentation in doc/c-code-generator.{html,xml}.
Relevant material has been updated and incorporated into the Doxygen
documentation in the protobuf-c header file.
* Remove the protobuf_c_default_allocator and protobuf_c_system_allocator
global variables from the exported library interface. All exported library
functions that need to perform dynamic memory allocation receive a
user-provided ProtobufCAllocator* parameter. If this parameter is NULL,
the system's default memory allocator will be used.
Client code that previously passed "&protobuf_c_system_allocator" to
protobuf-c library functions taking a ProtobufCAllocator* argument should
be updated to pass "NULL" instead.
Client code that previously overrode protobuf_c_default_allocator with
custom allocation functions and passed NULL as the ProtobufCAllocator*
argument to protobuf-c library functions should be updated to instead
enclose the custom allocation functions in a ProtobufCAllocator struct and
pass this object to protobuf-c library functions taking a
ProtobufCAllocator* parameter.
* Update copyright and license statements throughout. The original
protobuf code released by Google was relicensed from Apache-2.0 to
BSD-3-Clause. Dave Benson also converted his license from BSD-3-Clause
to BSD-2-Clause.
[ Tomasz Wasilczyk ]
* Don't export protobuf_c_message_init_generic() as an external symbol.
* Don't use C++ style comments in C code.
* Fix -Wcast-align warnings when compiled with clang.
protobuf-c (0.15)
- make protobuf_c_message_init() into a function (Issue #49, daveb)
- Fix for freeing memory after unpacking bytes w/o a default-value.
(Andrei Nigmatulin)
- minor windows portability issues (use ProtobufC_FD) (Pop Stelian)
- --with-endianness={little,big} (Pop Stelian)
- bug setting up values of has_idle in public dispatch,
make protobuf_c_dispatch_run() use only public members (daveb)
- provide cmake support and some Windows compatibility (Nikita Manovich)
protobuf-c (0.14)
- build fix (missing dependency in test directory)
- add generation / installation of pkg-config files. (Bobby Powers)
- support for packed repeated fields (Dave Benson)
- bug in protobuf_c_dispatch_close_fd(), which usually only
showed up in later function calls.
- support for deprecated fields -- enable a GCC warning
if a field has the "deprecated" option enabled. (Andrei Nigmatulin)
- hackery to try to avoid touching inttypes.h on windows (Issue #41)
- fix for protobuf_c_message_unpack() to issue error if any
"required" field is missing in input stream. (Andrei Nigmatulin)
protobuf-c (0.13)
- Fix for when the number of connections gets too great in RPC.
(Leszek Swirski) (issue #32)
- Add --disable-protoc to only build libprotobuf-c (daveb)
- Bug fixes for protobuf_c_enum_descriptor_get_value_by_name()
and protobuf_c_service_descriptor_get_method_by_name()
- if descriptor->message_init != NULL, use it from unpack()
as an optimization (daveb)
- implement protobuf_c_{client,server}_set_error_handler()
protobuf-c (0.12)
- for field names which are reserved words, use the real name
given in the protobuf-c file, not the mangled name which
is the name of the member in the C structure. (Andrei Nigmatulin)
- add protobuf_c_message_init() function; add virtual function
that implements it efficiently. (Andrei Nigmatulin)
- bug fix for sfixed32, fixed32, float wire-types on
big-endian platforms (Robert Edmonds)
- compile with the latest protobuf (the header file wire_format_inl.h
is now wire_format.h) (Robert Edmonds)
protobuf-c (0.11)
- allow CFLAGS=-DPRINT_UNPACK_ERRORS=0 to suppress
unpack warnings from being printed at compile time (Andrei Nigmatulin)
- give error if an unknown wire-type is encountered (Andrei Nigmatulin)
- fix technically possible overflows during unpack of very
large messages (Andrei Nigmatulin)
- [UNFINISHED] windows RPC work
- use automake's "foreign" mode from within configure.ac
and add version information to the library (Robert Edmonds)
- ProtobufCServiceDescriptor::method_indices_by_name: missing
const. (Issue 21)
- Update to support new UnknownFields API. (fix by dcreager) (Issue 20)
protobuf-c (0.10)
- build issue on platforms which don't compute library dependencies
automatically.
- fix for certain types of corrupt messages (Landon Fuller) (issue 16)
protobuf-c (0.9)
- build issue: needed $(EXEEXT) in dependency lists for cygwin
- bug fix: protobuf_c_service_get_method_by_name() was not correct b/c
the service's methods were not sorted by name (the header file
used to incorrectly state that they were).
Now we correctly implement protobuf_c_service_get_method_by_name()
(using a bsearch indexed by separate array).
- generated source incompatibility: we added a new
member to ProtobufCServiceDescriptor (method_indices_by_name).
You will have to run the latest protobuf
to generate those structures.
- rename rpc-client's "autoretry" mechanism to "autoreconnect".
- bug fixes using TCP clients with the RPC system.
- handle allocation failures more gracefully (Jason Lunz) (issue 15)
protobuf-c (0.8)
- Destroy function typedef for Services was omitting a "*"
- service_machgen_invoke was broken. (issue 12)
- add RPC system (BETA)
- don't segfault when packing NULL strings and messages. (issue 13)
protobuf-c (0.7)
- memory leak: unknown fields were not being freed by free_unpacked()
- lowercase field names consistently when composing
default_value names. (issue 11)
- remove spurious semicolon (issue 10)
protobuf-c (0.6)
- Warning suppression for -Wcast-qual and -Wshadow.
- Support for default values of all types allowed by core protobuf.
- Generate message__init functions, for when the static initializer
isn't convenient.
- add some reserved fields at the end of the various descriptors
protobuf-c (0.5)
- License now included in major files.
- Use little-endian optimizations; fix a bug therein.
- Include 'make deb' target.
protobuf-c (0.4)
- Update to work with protobuf 2.0.1.
protobuf-c (0.2)
protobuf-c (0.3)
- Minor pedantic concerns about generated code.
protobuf-c (0.1)
- Lots of test code (and bug fixes).
protobuf-c (0.0)
- Initial release.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.7 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<detaileddescription title=""/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@@ -0,0 +1,32 @@
Copyright (c) 2008-2022, Dave Benson and the protobuf-c authors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The code generated by the protoc-gen-c code generator and by the
protoc-c compiler is owned by the owner of the input files used when
generating it. This code is not standalone and requires a support
library to be linked with it. This support library is covered by the
above license.

View File

@@ -0,0 +1,382 @@
bin_PROGRAMS =
check_PROGRAMS =
noinst_PROGRAMS =
lib_LTLIBRARIES =
nobase_include_HEADERS =
pkgconfig_DATA =
BUILT_SOURCES =
TESTS =
CLEANFILES =
DISTCLEANFILES =
EXTRA_DIST =
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
EXTRA_DIST += LICENSE
EXTRA_DIST += README.md
AM_CPPFLAGS = \
-include $(top_builddir)/config.h \
-I${top_srcdir}/protobuf-c \
-I${top_builddir} \
-I${top_srcdir}
AM_CFLAGS = ${my_CFLAGS}
AM_LDFLAGS =
# code coverage
AM_CFLAGS += ${CODE_COVERAGE_CFLAGS}
AM_LDFLAGS += ${CODE_COVERAGE_LDFLAGS}
CODE_COVERAGE_LCOV_OPTIONS = --no-external
CODE_COVERAGE_IGNORE_PATTERN = "$(abs_top_builddir)/t/*"
@CODE_COVERAGE_RULES@
#
# libprotobuf-c
#
LIBPROTOBUF_C_CURRENT=1
LIBPROTOBUF_C_REVISION=0
LIBPROTOBUF_C_AGE=0
lib_LTLIBRARIES += \
protobuf-c/libprotobuf-c.la
nobase_include_HEADERS += \
protobuf-c/protobuf-c.h \
protobuf-c/protobuf-c.proto
protobuf_c_libprotobuf_c_la_SOURCES = \
protobuf-c/protobuf-c.c \
protobuf-c/protobuf-c.h
protobuf_c_libprotobuf_c_la_LDFLAGS = $(AM_LDFLAGS) \
-version-info $(LIBPROTOBUF_C_CURRENT):$(LIBPROTOBUF_C_REVISION):$(LIBPROTOBUF_C_AGE) \
-no-undefined
if HAVE_LD_VERSION_SCRIPT
protobuf_c_libprotobuf_c_la_LDFLAGS += \
-Wl,--version-script=$(top_srcdir)/protobuf-c/libprotobuf-c.sym
else
protobuf_c_libprotobuf_c_la_LDFLAGS += \
-export-symbols-regex "^(protobuf_c_[a-z].*)"
endif
EXTRA_DIST += protobuf-c/libprotobuf-c.sym
pkgconfig_DATA += protobuf-c/libprotobuf-c.pc
CLEANFILES += protobuf-c/libprotobuf-c.pc
EXTRA_DIST += protobuf-c/libprotobuf-c.pc.in
#
# protoc-gen-c
#
if BUILD_COMPILER
bin_PROGRAMS += protoc-c/protoc-gen-c
protoc_c_protoc_gen_c_SOURCES = \
protoc-c/c_bytes_field.cc \
protoc-c/c_bytes_field.h \
protoc-c/c_enum.cc \
protoc-c/c_enum.h \
protoc-c/c_enum_field.cc \
protoc-c/c_enum_field.h \
protoc-c/c_extension.cc \
protoc-c/c_extension.h \
protoc-c/c_field.cc \
protoc-c/c_field.h \
protoc-c/c_file.cc \
protoc-c/c_file.h \
protoc-c/c_generator.cc \
protoc-c/c_generator.h \
protoc-c/c_helpers.cc \
protoc-c/c_helpers.h \
protoc-c/c_message.cc \
protoc-c/c_message.h \
protoc-c/c_message_field.cc \
protoc-c/c_message_field.h \
protoc-c/c_primitive_field.cc \
protoc-c/c_primitive_field.h \
protoc-c/c_service.cc \
protoc-c/c_service.h \
protoc-c/c_string_field.cc \
protoc-c/c_string_field.h \
protobuf-c/protobuf-c.pb.cc \
protobuf-c/protobuf-c.pb.h \
protoc-c/main.cc
protoc_c_protoc_gen_c_CXXFLAGS = \
$(AM_CXXFLAGS) \
$(protobuf_CFLAGS)
protoc_c_protoc_gen_c_LDADD = \
$(protobuf_LIBS) \
-lprotoc
protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h: @PROTOC@ $(top_srcdir)/protobuf-c/protobuf-c.proto
$(AM_V_GEN)@PROTOC@ -I$(top_srcdir) --cpp_out=$(top_builddir) $(top_srcdir)/protobuf-c/protobuf-c.proto
BUILT_SOURCES += \
protobuf-c/protobuf-c.pb.cc \
protobuf-c/protobuf-c.pb.h
#
# protoc-c compat link
#
install-exec-hook:
rm -f $(DESTDIR)$(bindir)/protoc-c
ln -s protoc-gen-c $(DESTDIR)$(bindir)/protoc-c
#
# protobuf-c tests
#
if CROSS_COMPILING
#
# skip tests on cross-compiling
#
else
LOG_COMPILER = $(VALGRIND)
check_PROGRAMS += \
t/generated-code/test-generated-code \
t/generated-code2/test-generated-code2 \
t/version/version
TESTS += \
t/generated-code/test-generated-code \
t/generated-code2/test-generated-code2 \
t/version/version
t_generated_code_test_generated_code_SOURCES = \
t/generated-code/test-generated-code.c \
t/test.pb-c.c
t_generated_code_test_generated_code_LDADD = \
protobuf-c/libprotobuf-c.la
t_generated_code2_test_generated_code2_SOURCES = \
t/generated-code2/test-generated-code2.c \
t/test-full.pb-c.c \
t/test-optimized.pb-c.c
t_generated_code2_test_generated_code2_LDADD = \
protobuf-c/libprotobuf-c.la
noinst_PROGRAMS += \
t/generated-code2/cxx-generate-packed-data
t_generated_code2_cxx_generate_packed_data_SOURCES = \
t/generated-code2/cxx-generate-packed-data.cc \
t/test-full.pb.cc \
protobuf-c/protobuf-c.pb.cc
$(t_generated_code2_cxx_generate_packed_data_OBJECTS): t/test-full.pb.h
t_generated_code2_cxx_generate_packed_data_CXXFLAGS = \
$(AM_CXXFLAGS) \
$(protobuf_CFLAGS)
t_generated_code2_cxx_generate_packed_data_LDADD = \
$(protobuf_LIBS)
t/test.pb-c.c t/test.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test.proto
t/test-optimized.pb-c.c t/test-optimized.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-optimized.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-optimized.proto
t/test-full.pb-c.c t/test-full.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-full.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-full.proto
t/test-full.pb.cc t/test-full.pb.h: @PROTOC@ $(top_srcdir)/t/test-full.proto
$(AM_V_GEN)@PROTOC@ -I$(top_srcdir) --cpp_out=$(top_builddir) $(top_srcdir)/t/test-full.proto
t/generated-code2/test-full-cxx-output.inc: t/generated-code2/cxx-generate-packed-data$(EXEEXT)
$(AM_V_GEN)$(top_builddir)/t/generated-code2/cxx-generate-packed-data$(EXEEXT) > $(top_builddir)/t/generated-code2/test-full-cxx-output.inc
BUILT_SOURCES += \
t/test.pb-c.c t/test.pb-c.h \
t/test-full.pb-c.c t/test-full.pb-c.h \
t/test-optimized.pb-c.c t/test-optimized.pb-c.h \
t/test-full.pb.cc t/test-full.pb.h \
t/generated-code2/test-full-cxx-output.inc
if BUILD_PROTO3
check_PROGRAMS += \
t/generated-code3/test-generated-code3
TESTS += \
t/generated-code3/test-generated-code3
t_generated_code3_test_generated_code3_CPPFLAGS = \
-DPROTO3
t_generated_code3_test_generated_code3_LDADD = \
protobuf-c/libprotobuf-c.la
t_generated_code3_test_generated_code3_SOURCES = \
t/generated-code/test-generated-code.c \
t/test-proto3.pb-c.c
t/test-proto3.pb-c.c t/test-proto3.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/test-proto3.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/test-proto3.proto
BUILT_SOURCES += \
t/test-proto3.pb-c.c t/test-proto3.pb-c.h
endif # BUILD_PROTO3
t_version_version_SOURCES = \
t/version/version.c
t_version_version_LDADD = \
protobuf-c/libprotobuf-c.la
# Issue #204
check_PROGRAMS += \
t/issue204/issue204
TESTS += \
t/issue204/issue204
t_issue204_issue204_SOURCES = \
t/issue204/issue204.c \
t/issue204/issue204.pb-c.c
t_issue204_issue204_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue204/issue204.pb-c.c t/issue204/issue204.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue204/issue204.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue204/issue204.proto
BUILT_SOURCES += \
t/issue204/issue204.pb-c.c t/issue204/issue204.pb-c.h
EXTRA_DIST += \
t/issue204/issue204.proto
# Issue #220
check_PROGRAMS += \
t/issue220/issue220
TESTS += \
t/issue220/issue220
t_issue220_issue220_SOURCES = \
t/issue220/issue220.c \
t/issue220/issue220.pb-c.c
t_issue220_issue220_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue220/issue220.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue220/issue220.proto
BUILT_SOURCES += \
t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h
EXTRA_DIST += \
t/issue220/issue220.proto
# Issue #251
check_PROGRAMS += \
t/issue251/issue251
TESTS += \
t/issue251/issue251
t_issue251_issue251_SOURCES = \
t/issue251/issue251.c \
t/issue251/issue251.pb-c.c
t_issue251_issue251_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue251/issue251.pb-c.c t/issue251/issue251.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue251/issue251.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue251/issue251.proto
BUILT_SOURCES += \
t/issue251/issue251.pb-c.c t/issue251/issue251.pb-c.h
EXTRA_DIST += \
t/issue251/issue251.proto
# Issue #330
if BUILD_PROTO3
check_PROGRAMS += \
t/issue330/issue330
TESTS += \
t/issue330/issue330
t_issue330_issue330_SOURCES = \
t/issue330/issue330.c \
t/issue330/issue330.pb-c.c
t_issue330_issue330_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue330/issue330.pb-c.c t/issue330/issue330.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue330/issue330.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue330/issue330.proto
BUILT_SOURCES += \
t/issue330/issue330.pb-c.c t/issue330/issue330.pb-c.h
t_issue330_issue330_SOURCES += \
t/issue389/issue389.pb-c.c # Tack onto issue330 since there is no need for a separate binary here
t/issue389/issue389.pb-c.c t/issue389/issue389.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue389/issue389.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue389/issue389.proto
BUILT_SOURCES += \
t/issue389/issue389.pb-c.c t/issue389/issue389.pb-c.h
EXTRA_DIST += \
t/issue389/issue389.proto
check_PROGRAMS += \
t/issue440/issue440
TESTS += \
t/issue440/issue440
t_issue440_issue440_SOURCES = \
t/issue440/issue440.c \
t/issue440/issue440.pb-c.c
t_issue440_issue440_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue440/issue440.pb-c.c t/issue440/issue440.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue440/issue440.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue440/issue440.proto
BUILT_SOURCES += \
t/issue440/issue440.pb-c.c t/issue440/issue440.pb-c.h
EXTRA_DIST += \
t/issue440/issue440.proto
endif # BUILD_PROTO3
EXTRA_DIST += \
t/issue330/issue330.proto
# Issue #375
check_PROGRAMS += \
t/issue375/issue375
TESTS += \
t/issue375/issue375
t_issue375_issue375_SOURCES = \
t/issue375/issue375.c \
t/issue375/issue375.pb-c.c
t_issue375_issue375_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue375/issue375.pb-c.c t/issue375/issue375.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue375/issue375.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue375/issue375.proto
BUILT_SOURCES += \
t/issue375/issue375.pb-c.c t/issue375/issue375.pb-c.h
EXTRA_DIST += \
t/issue375/issue375.proto
endif # CROSS_COMPILING
endif # BUILD_COMPILER
EXTRA_DIST += \
t/test.proto \
t/test-full.proto \
t/test-optimized.proto \
t/test-proto3.proto \
t/generated-code2/common-test-arrays.h
#
#
#
CLEANFILES += $(BUILT_SOURCES)
dist-hook:
rm -f `find $(distdir) -name '*.pb-c.[ch]' -o -name '*.pb.cc' -o -name '*.pb.h'`
install-data-hook:
$(MKDIR_P) $(DESTDIR)$(includedir)/google/protobuf-c
cd $(DESTDIR)$(includedir)/google/protobuf-c && rm -f protobuf-c.h
cd $(DESTDIR)$(includedir)/google/protobuf-c && $(LN_S) ../../protobuf-c/protobuf-c.h protobuf-c.h
#
# documentation
#
if HAVE_DOXYGEN
stamp-html: $(DOXYGEN_INPUT_FILES) $(top_builddir)/Doxyfile $(top_srcdir)/DoxygenLayout.xml $(include_HEADERS) $(nobase_include_HEADERS)
$(AM_V_GEN) $(DOXYGEN)
@touch $@
html-local: stamp-html
clean-local:
rm -rf $(top_builddir)/html $(top_builddir)/stamp-html
endif
EXTRA_DIST += Doxyfile.in
EXTRA_DIST += DoxygenLayout.xml
EXTRA_DIST += build-cmake/CMakeLists.txt

View File

@@ -0,0 +1,73 @@
[![Build Status](https://github.com/protobuf-c/protobuf-c/actions/workflows/build.yml/badge.svg)](https://github.com/protobuf-c/protobuf-c/actions) [![Coverage Status](https://coveralls.io/repos/protobuf-c/protobuf-c/badge.png)](https://coveralls.io/r/protobuf-c/protobuf-c)
## Overview
This is `protobuf-c`, a C implementation of the [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) data serialization format. It includes `libprotobuf-c`, a pure C library that implements protobuf encoding and decoding, and `protoc-c`, a code generator that converts Protocol Buffer `.proto` files to C descriptor code, based on the original `protoc`. `protobuf-c` formerly included an RPC implementation; that code has been split out into the [protobuf-c-rpc](https://github.com/protobuf-c/protobuf-c-rpc) project.
`protobuf-c` was originally written by Dave Benson and maintained by him through version 0.15 but is now being maintained by a new team. Thanks, Dave!
## Mailing list
`protobuf-c`'s mailing list is hosted on a [Google Groups forum](https://groups.google.com/forum/#!forum/protobuf-c). Subscribe by sending an email to [protobuf-c+subscribe@googlegroups.com](mailto:protobuf-c+subscribe@googlegroups.com).
## Building
`protobuf-c` requires a C compiler, a C++ compiler, [protobuf](https://github.com/google/protobuf), and `pkg-config` to be installed.
./configure && make && make install
If building from a git checkout, the `autotools` (`autoconf`, `automake`, `libtool`) must also be installed, and the build system must be generated by running the `autogen.sh` script.
./autogen.sh && ./configure && make && make install
## Test
If you want to execute test cases individually, please run the following command after running `./configure` once:
make check
## Documentation
See the [online Doxygen documentation here](https://protobuf-c.github.io/protobuf-c) or [the Wiki](https://github.com/protobuf-c/protobuf-c/wiki) for a detailed reference. The Doxygen documentation can be built from the source tree by running:
make html
## Synopsis
Use the `protoc` command to generate `.pb-c.c` and `.pb-c.h` output files from your `.proto` input file. The `--c_out` options instructs `protoc` to use the protobuf-c plugin.
protoc --c_out=. example.proto
Include the `.pb-c.h` file from your C source code.
#include "example.pb-c.h"
Compile your C source code together with the `.pb-c.c` file. Add the output of the following command to your compile flags.
pkg-config --cflags 'libprotobuf-c >= 1.0.0'
Link against the `libprotobuf-c` support library. Add the output of the following command to your link flags.
pkg-config --libs 'libprotobuf-c >= 1.0.0'
If using autotools, the `PKG_CHECK_MODULES` macro can be used to detect the presence of `libprotobuf-c`. Add the following line to your `configure.ac` file:
PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c >= 1.0.0])
This will place compiler flags in the `PROTOBUF_C_CFLAGS` variable and linker flags in the `PROTOBUF_C_LDFLAGS` variable. Read [more information here](https://autotools.io/pkgconfig/pkg_check_modules.html) about the `PKG_CHECK_MODULES` macro.
## Versioning
`protobuf-c` follows the [Semantic Versioning Specification](http://semver.org/) as of version 1.0.0.
Note that as of version of 1.0.0, the header files generated by the `protoc-c` compiler contain version guards to prevent incompatibilities due to version skew between the `.pb-c.h` files generated by `protoc-c` and the public `protobuf-c.h` include file supplied by the `libprotobuf-c` support library. While we will try not to make changes to `protobuf-c` that will require triggering the version guard often, such as releasing a new major version of `protobuf-c`, this cannot be guaranteed. Thus, it's a good idea to recompile your `.pb-c.c` and `.pb-c.h` files from their source `.proto` files with `protoc-c` as part of your build system, with proper source file dependency tracking, rather than shipping potentially stale `.pb-c.c` and `.pb-c.h` files that may not be compatible with the `libprotobuf-c` headers installed on the system in project artifacts like repositories and release tarballs. (Note that the output of the `protoc-c` code generator is not standalone, as the output of some other tools that generate C code is, such as `flex` and `bison`.)
Major API/ABI changes may occur between major version releases, by definition. It is not recommended to export the symbols in the code generated by `protoc-c` in a stable library interface, as this will embed the `protobuf-c` ABI into your library's ABI. Nor is it recommended to install generated `.pb-c.h` files into a public header file include path as part of a library API, as this will tie clients of your library's API to particular versions of `libprotobuf-c`.
## Contributing
Please send patches to the [protobuf-c mailing list](https://groups.google.com/forum/#!forum/protobuf-c) or by opening a GitHub pull request.
The most recently released `protobuf-c` version is kept on the `master` branch, while the `next` branch is used for commits targeted at the next release. Please base patches and pull requests against the `next` branch, not the `master` branch.
Copyright to all contributions are retained by the original author, but must be licensed under the terms of the [BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause) license. Please add a `Signed-off-by` header to your commit message (`git commit -s`) to indicate that you are licensing your contribution under these terms.

View File

@@ -0,0 +1,82 @@
----------------------
--- IMPORTANT TODO ---
----------------------
--------------------
--- NEEDED TESTS ---
--------------------
- test:
- service method lookups
- out-of-order fields in messages (ie if the number isn't ascending)
- gaps in numbers: check that the number of ranges is correct
- default values
- message unpack alloc failures when allocating new slab
- message unpack alloc failures when allocating unknown field buffers
- packed message corruption.
- meta-todo: get a list of all the unpack errors together to check off
---------------------
--- DOCUMENTATION ---
---------------------
Document:
- services
- check over documentation again
--------------------------
--- LOW PRIORITY STUFF ---
--------------------------
- support Group (whatever it is)
- proper support for extensions
- slot for ranges in descriptor
- extends is implemented as c-style function
whose name is built from the package, the base message type-name
and the member. which takes the base message and returns the
value, if it is found in "unknown_values".
boolean package__extension_member_name__get(Message *message,
type *out);
void package__extension_member_name__set_raw(type in,
ProtobufCUnknownValue *to_init);
------------------------------------
--- EXTREMELY LOW PRIORITY STUFF ---
------------------------------------
- stop using qsort in the code generator: find some c++ish way to do it
----------------------------------------------
--- ISSUES WE ARE PROBABLY GOING TO IGNORE ---
----------------------------------------------
- strings may not contain NULs
-------------------------
--- IDEAS TO CONSIDER ---
-------------------------
- optimization: structures without repeated members could skip
the ScannedMember phase
- optimization: a way to ignore unknown-fields when unpacking
- optimization: certain functions are not well setup for WORDSIZE==64;
especially the int64 routines are inefficient that way.
The best might be an internal #define WORDSIZE (sizeof(long)*8)"
except w/ a real constant there, one that the preprocessor can use.
I think the functions in protobuf-c.c are already tagged.
- lifetime functions for messages:
message__new()
return a new message using an allocator with standard allocation policy
message__unpack_onto(...)
unpack onto an initialized message
message__clear(...)
clears all allocations, does not free the message itself
message__free(...)
free the message.
[yeah, right: after typing it out, i see it's way too complicated]
- switching to pure C.
- Rewrite the code-generator in C, including the parser.
- This would have the huge advantage that we could use ".proto" files
directly, instead of having to invoke the compilers.
- keep in a separate c file for static linking optimziation purposes
- need alignment tests
- the CAVEATS should discuss our structure-packing assumptions

View File

@@ -0,0 +1,2 @@
#!/bin/sh
exec autoreconf -fvi

View File

@@ -0,0 +1,3 @@
*
!.gitignore
!CMakeLists.txt

View File

@@ -0,0 +1,218 @@
SET(PACKAGE protobuf-c)
SET(PACKAGE_NAME protobuf-c)
SET(PACKAGE_VERSION 1.4.1)
SET(PACKAGE_URL https://github.com/protobuf-c/protobuf-c)
SET(PACKAGE_DESCRIPTION "Protocol Buffers implementation in C")
CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR)
PROJECT(protobuf-c)
#options
option(BUILD_PROTO3 "BUILD_PROTO3" ON)
option(BUILD_PROTOC "Build protoc-gen-c" ON)
if(CMAKE_BUILD_TYPE MATCHES Debug)
option(BUILD_TESTS "Build tests" ON)
else()
option(BUILD_TESTS "Build tests" OFF)
endif()
INCLUDE(TestBigEndian)
TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
SET(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
ADD_DEFINITIONS(-DPACKAGE_VERSION="${PACKAGE_VERSION}")
ADD_DEFINITIONS(-DPACKAGE_STRING="${PACKAGE_STRING}")
if (${WORDS_BIGENDIAN})
ADD_DEFINITIONS(-DWORDS_BIGENDIAN)
endif()
IF (MSVC AND BUILD_SHARED_LIBS)
ADD_DEFINITIONS(-DPROTOBUF_C_USE_SHARED_LIB)
ENDIF (MSVC AND BUILD_SHARED_LIBS)
if(MSVC)
# using Visual Studio C++
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4267 /wd4244")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4244")
ENDIF()
get_filename_component(MAIN_DIR ${CMAKE_CURRENT_SOURCE_DIR} PATH)
SET(TEST_DIR ${MAIN_DIR}/t)
MESSAGE(${MAIN_DIR})
SET (PC_SOURCES
${MAIN_DIR}/protobuf-c/protobuf-c.c
${MAIN_DIR}/protobuf-c/protobuf-c.h)
ADD_LIBRARY(protobuf-c ${PC_SOURCES})
set_target_properties(protobuf-c PROPERTIES COMPILE_PDB_NAME protobuf-c)
IF (MSVC AND BUILD_SHARED_LIBS)
TARGET_COMPILE_DEFINITIONS(protobuf-c PRIVATE -DPROTOBUF_C_EXPORT)
ENDIF (MSVC AND BUILD_SHARED_LIBS)
INCLUDE_DIRECTORIES(${MAIN_DIR})
INCLUDE_DIRECTORIES(${MAIN_DIR}/protobuf-c)
IF(BUILD_PROTOC)
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) # for generated files
if (MSVC AND NOT BUILD_SHARED_LIBS)
SET(Protobuf_USE_STATIC_LIBS ON)
endif (MSVC AND NOT BUILD_SHARED_LIBS)
FIND_PACKAGE(Protobuf REQUIRED)
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
if (BUILD_PROTO3)
ADD_DEFINITIONS(-DHAVE_PROTO3)
endif()
ENDIF()
if (MSVC AND NOT BUILD_SHARED_LIBS)
# In case we are building static libraries, link also the runtime library statically
# so that MSVCR*.DLL is not required at runtime.
# https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx
# This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach(flag_var)
endif (MSVC AND NOT BUILD_SHARED_LIBS)
IF(BUILD_PROTOC)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)
ADD_CUSTOM_COMMAND(OUTPUT protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_BINARY_DIR} -I${MAIN_DIR} ${MAIN_DIR}/protobuf-c/protobuf-c.proto)
FILE(GLOB PROTOC_GEN_C_SRC ${MAIN_DIR}/protoc-c/*.h ${MAIN_DIR}/protoc-c/*.cc )
ADD_EXECUTABLE(protoc-gen-c ${PROTOC_GEN_C_SRC} protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h)
TARGET_LINK_LIBRARIES(protoc-gen-c ${PROTOBUF_PROTOC_LIBRARY} ${PROTOBUF_LIBRARY})
IF (MSVC AND BUILD_SHARED_LIBS)
TARGET_COMPILE_DEFINITIONS(protoc-gen-c PRIVATE -DPROTOBUF_USE_DLLS)
GET_FILENAME_COMPONENT(PROTOBUF_DLL_DIR ${PROTOBUF_PROTOC_EXECUTABLE} DIRECTORY)
FILE(GLOB PROTOBUF_DLLS ${PROTOBUF_DLL_DIR}/*.dll)
FILE(COPY ${PROTOBUF_DLLS} DESTINATION ${CMAKE_BINARY_DIR})
ENDIF (MSVC AND BUILD_SHARED_LIBS)
IF(CMAKE_HOST_UNIX)
ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ln -sf protoc-gen-c protoc-c
DEPENDS protoc-gen-c)
ENDIF()
FUNCTION(GENERATE_TEST_SOURCES PROTO_FILE SRC HDR)
ADD_CUSTOM_COMMAND(OUTPUT ${SRC} ${HDR}
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --plugin=$<TARGET_FILE:protoc-gen-c> -I${MAIN_DIR} ${PROTO_FILE} --c_out=${CMAKE_BINARY_DIR}
DEPENDS protoc-gen-c)
ENDFUNCTION()
IF(BUILD_TESTS)
ENABLE_TESTING()
GENERATE_TEST_SOURCES(${TEST_DIR}/test.proto t/test.pb-c.c t/test.pb-c.h)
ADD_EXECUTABLE(test-generated-code ${TEST_DIR}/generated-code/test-generated-code.c t/test.pb-c.c t/test.pb-c.h )
TARGET_LINK_LIBRARIES(test-generated-code protobuf-c)
ADD_CUSTOM_COMMAND(OUTPUT t/test-full.pb.cc t/test-full.pb.h
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_BINARY_DIR} -I${MAIN_DIR} ${TEST_DIR}/test-full.proto)
GENERATE_TEST_SOURCES(${TEST_DIR}/test-full.proto t/test-full.pb-c.c t/test-full.pb-c.h)
ADD_EXECUTABLE(cxx-generate-packed-data ${TEST_DIR}/generated-code2/cxx-generate-packed-data.cc t/test-full.pb.h t/test-full.pb.cc protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h)
TARGET_LINK_LIBRARIES(cxx-generate-packed-data ${PROTOBUF_LIBRARY})
IF (MSVC AND BUILD_SHARED_LIBS)
TARGET_COMPILE_DEFINITIONS(cxx-generate-packed-data PRIVATE -DPROTOBUF_USE_DLLS)
ENDIF (MSVC AND BUILD_SHARED_LIBS)
FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/t/generated-code2)
ADD_CUSTOM_COMMAND(OUTPUT t/generated-code2/test-full-cxx-output.inc
COMMAND ${CMAKE_BINARY_DIR}/cxx-generate-packed-data ">t/generated-code2/test-full-cxx-output.inc"
DEPENDS cxx-generate-packed-data
)
GENERATE_TEST_SOURCES(${TEST_DIR}/test-optimized.proto t/test-optimized.pb-c.c t/test-optimized.pb-c.h)
ADD_EXECUTABLE(test-generated-code2 ${TEST_DIR}/generated-code2/test-generated-code2.c t/generated-code2/test-full-cxx-output.inc t/test-full.pb-c.h t/test-full.pb-c.c t/test-optimized.pb-c.h t/test-optimized.pb-c.c)
TARGET_LINK_LIBRARIES(test-generated-code2 protobuf-c)
GENERATE_TEST_SOURCES(${TEST_DIR}/issue220/issue220.proto t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h)
ADD_EXECUTABLE(test-issue220 ${TEST_DIR}/issue220/issue220.c t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h)
TARGET_LINK_LIBRARIES(test-issue220 protobuf-c)
GENERATE_TEST_SOURCES(${TEST_DIR}/issue251/issue251.proto t/issue251/issue251.pb-c.c t/issue251/issue251.pb-c.h)
ADD_EXECUTABLE(test-issue251 ${TEST_DIR}/issue251/issue251.c t/issue251/issue251.pb-c.c t/issue251/issue251.pb-c.h)
TARGET_LINK_LIBRARIES(test-issue251 protobuf-c)
ADD_EXECUTABLE(test-version ${TEST_DIR}/version/version.c)
TARGET_LINK_LIBRARIES(test-version protobuf-c)
GENERATE_TEST_SOURCES(${TEST_DIR}/test-proto3.proto t/test-proto3.pb-c.c t/test-proto3.pb-c.h)
ADD_EXECUTABLE(test-generated-code3 ${TEST_DIR}/generated-code/test-generated-code.c t/test-proto3.pb-c.c t/test-proto3.pb-c.h)
TARGET_COMPILE_DEFINITIONS(test-generated-code3 PUBLIC -DPROTO3)
TARGET_LINK_LIBRARIES(test-generated-code3 protobuf-c)
ENDIF() # BUILD_TESTS
# https://github.com/protocolbuffers/protobuf/issues/5107
IF(CMAKE_HOST_UNIX)
FIND_PACKAGE(Threads REQUIRED)
TARGET_LINK_LIBRARIES(protoc-gen-c ${CMAKE_THREAD_LIBS_INIT})
IF(BUILD_TESTS)
TARGET_LINK_LIBRARIES(cxx-generate-packed-data ${CMAKE_THREAD_LIBS_INIT})
ENDIF()
ENDIF()
INSTALL(TARGETS protoc-gen-c RUNTIME DESTINATION bin)
ENDIF() # BUILD_PROTOC
INSTALL(TARGETS protobuf-c LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin)
INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h ${MAIN_DIR}/protobuf-c/protobuf-c.proto DESTINATION include/protobuf-c)
INSTALL(FILES ${MAIN_DIR}/protobuf-c/protobuf-c.h DESTINATION include)
INSTALL(FILES ${CMAKE_BINARY_DIR}/protobuf-c.pdb DESTINATION lib OPTIONAL)
IF(CMAKE_HOST_UNIX)
INSTALL(CODE "EXECUTE_PROCESS (COMMAND ln -sf protoc-gen-c protoc-c WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)")
ENDIF()
INCLUDE(GNUInstallDirs)
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix \${prefix})
SET(bindir \${exec_prefix}/${CMAKE_INSTALL_BINDIR})
SET(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
SET(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
CONFIGURE_FILE(${MAIN_DIR}/protobuf-c/libprotobuf-c.pc.in libprotobuf-c.pc @ONLY)
INSTALL(FILES ${CMAKE_BINARY_DIR}/libprotobuf-c.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
IF(BUILD_TESTS)
INCLUDE(Dart)
SET(DART_TESTING_TIMEOUT 5)
ADD_TEST(test-generated-code test-generated-code)
ADD_TEST(test-generated-code2 test-generated-code2)
ADD_TEST(test-generated-code3 test-generated-code3)
ADD_TEST(test-issue220 test-issue220)
ADD_TEST(test-issue251 test-issue251)
ADD_TEST(test-version test-version)
ENDIF()
INCLUDE(CPack)

View File

@@ -0,0 +1,139 @@
AC_PREREQ(2.63)
AC_INIT([protobuf-c],
[1.4.1],
[https://github.com/protobuf-c/protobuf-c/issues],
[protobuf-c],
[https://github.com/protobuf-c/protobuf-c])
PACKAGE_DESCRIPTION="Protocol Buffers implementation in C"
AC_SUBST(PACKAGE_DESCRIPTION)
AC_CONFIG_SRCDIR([protobuf-c/protobuf-c.c])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules subdir-objects])
AC_PROG_CC_STDC
AC_PROG_CXX
AC_PROG_LN_S
AC_PROG_MKDIR_P
AC_USE_SYSTEM_EXTENSIONS
AC_SYS_LARGEFILE
AC_CONFIG_MACRO_DIR([m4])
AM_SILENT_RULES([yes])
LT_INIT
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_FILES([Makefile protobuf-c/libprotobuf-c.pc])
my_CFLAGS="\
-Wall \
-Wchar-subscripts \
-Wdeclaration-after-statement \
-Wformat-security \
-Wmissing-declarations \
-Wmissing-prototypes \
-Wnested-externs \
-Wpointer-arith \
-Wshadow \
-Wsign-compare \
-Wstrict-prototypes \
-Wtype-limits \
"
#AX_CHECK_COMPILE_FLAG(["-Wc90-c99-compat"],
# [my_CFLAGS="$my_CFLAGS -Wc90-c99-compat"])
AX_CHECK_COMPILE_FLAG(["-Wc99-c11-compat"],
[my_CFLAGS="$my_CFLAGS -Wc99-c11-compat"])
AX_CHECK_COMPILE_FLAG(["-Werror=incompatible-pointer-types"],
[my_CFLAGS="$my_CFLAGS -Werror=incompatible-pointer-types"])
AX_CHECK_COMPILE_FLAG(["-Werror=int-conversion"],
[my_CFLAGS="$my_CFLAGS -Werror=int-conversion"])
AX_CHECK_COMPILE_FLAG(["-Wnull-dereference"],
[my_CFLAGS="$my_CFLAGS -Wnull-dereference"])
AC_SUBST([my_CFLAGS])
AC_CHECK_PROGS([DOXYGEN], [doxygen])
AM_CONDITIONAL([HAVE_DOXYGEN],
[test -n "$DOXYGEN"])
AM_COND_IF([HAVE_DOXYGEN],
[AC_CONFIG_FILES([Doxyfile])
DOXYGEN_INPUT="${srcdir}/protobuf-c"
AC_SUBST(DOXYGEN_INPUT)
])
PKG_PROG_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
# Horrible hack for systems where the pkg-config install directory is simply wrong!
if $PKG_CONFIG --variable=pc_path pkg-config 2>/dev/null | grep -q /libdata/; then
PKG_INSTALLDIR(['${prefix}/libdata/pkgconfig'])
else
PKG_INSTALLDIR
fi
fi
proto3_supported="no"
AC_ARG_ENABLE([protoc],
AS_HELP_STRING([--disable-protoc], [Disable building protoc_c (also disables tests)]))
if test "x$enable_protoc" != "xno"; then
AC_LANG_PUSH([C++])
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
PKG_CHECK_MODULES([protobuf], [protobuf >= 3.0.0],
[proto3_supported=yes],
[PKG_CHECK_MODULES([protobuf], [protobuf >= 2.6.0])]
)
save_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$save_CPPFLAGS $protobuf_CFLAGS"
AC_CHECK_HEADERS([google/protobuf/compiler/command_line_interface.h],
[],
[AC_MSG_ERROR([required protobuf header file not found])])
CPPFLAGS="$save_CPPFLAGS"
AC_ARG_VAR([PROTOC], [protobuf compiler command])
AC_PATH_PROG([PROTOC], [protoc], [],
[`$PKG_CONFIG --variable=exec_prefix protobuf`/bin:$PATH])
if test -z "$PROTOC"; then
AC_MSG_ERROR([Please install the protobuf compiler from https://code.google.com/p/protobuf/.])
fi
PROTOBUF_VERSION="$($PROTOC --version)"
else
PROTOBUF_VERSION="not required, not building compiler"
fi
AM_CONDITIONAL([BUILD_COMPILER], [test "x$enable_protoc" != "xno"])
AM_CONDITIONAL([BUILD_PROTO3], [test "x$proto3_supported" != "xno"])
AM_CONDITIONAL([CROSS_COMPILING], [test "x$cross_compiling" != "xno"])
AM_COND_IF([BUILD_PROTO3], [AC_DEFINE([HAVE_PROTO3], [1], [Support proto3 syntax])])
gl_LD_VERSION_SCRIPT
gl_VALGRIND_TESTS
MY_CODE_COVERAGE
AC_C_BIGENDIAN
AC_OUTPUT
AC_MSG_RESULT([
$PACKAGE $VERSION
CC: ${CC}
CFLAGS: ${CFLAGS}
CXX: ${CXX}
CXXFLAGS: ${CXXFLAGS}
LDFLAGS: ${LDFLAGS}
LIBS: ${LIBS}
prefix: ${prefix}
sysconfdir: ${sysconfdir}
libdir: ${libdir}
includedir: ${includedir}
pkgconfigdir: ${pkgconfigdir}
bigendian: ${ac_cv_c_bigendian}
protobuf version: ${PROTOBUF_VERSION}
])

View File

@@ -0,0 +1,5 @@
libtool.m4
ltoptions.m4
ltsugar.m4
ltversion.m4
lt~obsolete.m4

View File

@@ -0,0 +1,74 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 5
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

View File

@@ -0,0 +1,948 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
# required and that the macro should error out if no mode with that
# support is found. If specified 'optional', then configuration proceeds
# regardless, after defining HAVE_CXX${VERSION} if and only if a
# supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 10
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
[$2], [noext], [],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
fi])
m4_if([$2], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
HAVE_CXX$1=0
AC_MSG_NOTICE([No compiler with C++$1 support was found])
else
HAVE_CXX$1=1
AC_DEFINE(HAVE_CXX$1,1,
[define if the compiler supports basic C++$1 syntax])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual void f() {}
};
struct Derived : public Base
{
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])

View File

@@ -0,0 +1,158 @@
# SYNOPSIS
#
# MY_CODE_COVERAGE()
#
# DESCRIPTION
#
# Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be
# included in the CFLAGS and LIBS/LDFLAGS variables of every build target
# (program or library) which should be built with code coverage support.
# Also defines CODE_COVERAGE_RULES which should be substituted in your
# Makefile; and $enable_code_coverage which can be used in subsequent
# configure output. CODE_COVERAGE_ENABLED is defined and substituted, and
# corresponds to the value of the --enable-code-coverage option, which
# defaults to being disabled.
#
# Usage example:
# configure.ac:
# MY_CODE_COVERAGE
#
# Makefile.am:
# @CODE_COVERAGE_RULES@
# my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) …
# my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) …
#
# This results in a “check-code-coverage” rule being added to any Makefile.am
# which includes “@CODE_COVERAGE_RULES@” (assuming the module has been
# configured with --enable-code-coverage). Running `make check-code-coverage`
# in that directory will run the modules test suite (`make check`) and build
# a code coverage report detailing the code which was touched, then print the
# URI for the report.
#
# LICENSE
#
# Copyright © 2012, 2014 Philip Withnall
# Copyright © 2012 Xan Lopez
# Copyright © 2012 Christian Persch
# Copyright © 2012 Paolo Borelli
# Copyright © 2012 Dan Winship
#
# Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+.
# This file is licenced under LGPLv2.1+.
AC_DEFUN([MY_CODE_COVERAGE],[
dnl Check for --enable-code-coverage
AC_MSG_CHECKING([whether to build with code coverage support])
AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no)
AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
AC_MSG_RESULT($enable_code_coverage)
AS_IF([ test "$enable_code_coverage" = "yes" ], [
dnl Check if gcc is being used
AS_IF([ test "$GCC" = "no" ], [
AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
])
AC_CHECK_PROG([LCOV], [lcov], [lcov])
AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
AS_IF([ test -z "$LCOV" ], [
AC_MSG_ERROR([The lcov program was not found. Please install lcov!])
])
AS_IF([ test -z "$GENHTML" ], [
AC_MSG_ERROR([The genhtml program was not found. Please install lcov!])
])
dnl Build the code coverage flags
CODE_COVERAGE_CFLAGS="-O0 -g --coverage"
CODE_COVERAGE_LDFLAGS="--coverage"
AC_SUBST([CODE_COVERAGE_CFLAGS])
AC_SUBST([CODE_COVERAGE_LDFLAGS])
dnl Strip optimisation flags
changequote({,})
CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'`
changequote([,])
])
CODE_COVERAGE_RULES='
# Code coverage
#
# Optional:
# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
# (Default: $(top_builddir))
# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
# by lcov for code coverage. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
# reports to be created. (Default:
# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance.
# (Default: empty)
# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
# instance. (Default: empty)
# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
#
# The generated report will be titled using the $(PACKAGE_NAME) and
# $(PACKAGE_VERSION). In order to add the current git hash to the title,
# use the git-version-gen script, available online.
# Optional variables
CODE_COVERAGE_DIRECTORY ?= $(abs_top_builddir)
CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
CODE_COVERAGE_LCOV_OPTIONS ?=
CODE_COVERAGE_GENHTML_OPTIONS ?=
CODE_COVERAGE_IGNORE_PATTERN ?=
code_coverage_quiet = $(code_coverage_quiet_$(V))
code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
code_coverage_quiet_0 = --quiet
# Use recursive makes in order to ignore errors during check
check-code-coverage:
ifeq ($(CODE_COVERAGE_ENABLED),yes)
-$(MAKE) $(AM_MAKEFLAGS) -k check
$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
else
@echo "Need to reconfigure with --enable-code-coverage"
endif
# Capture code coverage data
code-coverage-capture: code-coverage-capture-hook
ifeq ($(CODE_COVERAGE_ENABLED),yes)
$(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS)
$(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)"
-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
LANG=C $(GENHTML) $(code_coverage_quiet) --prefix $(CODE_COVERAGE_DIRECTORY) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
else
@echo "Need to reconfigure with --enable-code-coverage"
endif
# Hook rule executed before code-coverage-capture, overridable by the user
code-coverage-capture-hook:
ifeq ($(CODE_COVERAGE_ENABLED),yes)
clean: code-coverage-clean
code-coverage-clean:
-$(LCOV) --directory $(CODE_COVERAGE_DIRECTORY) -z
-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
-find . -name "*.gcda" -o -name "*.gcov" -delete
endif
GITIGNOREFILES ?=
GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
DISTCHECK_CONFIGURE_FLAGS ?=
DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
'
AC_SUBST([CODE_COVERAGE_RULES])
m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
])

View File

@@ -0,0 +1,53 @@
# ld-version-script.m4 serial 3
dnl Copyright (C) 2008-2014 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson
# FIXME: The test below returns a false positive for mingw
# cross-compiles, 'local:' statements does not reduce number of
# exported symbols in a DLL. Use --disable-ld-version-script to work
# around the problem.
# gl_LD_VERSION_SCRIPT
# --------------------
# Check if LD supports linker scripts, and define automake conditional
# HAVE_LD_VERSION_SCRIPT if so.
AC_DEFUN([gl_LD_VERSION_SCRIPT],
[
AC_ARG_ENABLE([ld-version-script],
AS_HELP_STRING([--enable-ld-version-script],
[enable linker version script (default is enabled when possible)]),
[have_ld_version_script=$enableval], [])
if test -z "$have_ld_version_script"; then
AC_MSG_CHECKING([if LD -Wl,--version-script works])
save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
cat > conftest.map <<EOF
foo
EOF
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
[accepts_syntax_errors=yes], [accepts_syntax_errors=no])
if test "$accepts_syntax_errors" = no; then
cat > conftest.map <<EOF
VERS_1 {
global: sym;
};
VERS_2 {
global: sym;
} VERS_1;
EOF
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
[have_ld_version_script=yes], [have_ld_version_script=no])
else
have_ld_version_script=no
fi
rm -f conftest.map
LDFLAGS="$save_LDFLAGS"
AC_MSG_RESULT($have_ld_version_script)
fi
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
])

View File

@@ -0,0 +1,214 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# only at the first occurence in configure.ac, so if the first place
# it's called might be skipped (such as if it is within an "if", you
# have to call PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
# _PKG_SHORT_ERRORS_SUPPORTED
# -----------------------------
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])# _PKG_SHORT_ERRORS_SUPPORTED
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
# [ACTION-IF-NOT-FOUND])
#
#
# Note that if there is a possibility the first call to
# PKG_CHECK_MODULES might not happen, you should be sure to include an
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
#
#
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])# PKG_CHECK_MODULES
# PKG_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable pkgconfigdir as the location where a module
# should install pkg-config .pc files. By default the directory is
# $libdir/pkgconfig, but the default can be changed by passing
# DIRECTORY. The user can override through the --with-pkgconfigdir
# parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_INSTALLDIR
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable noarch_pkgconfigdir as the location where a
# module should install arch-independent pkg-config .pc files. By
# default the directory is $datadir/pkgconfig, but the default can be
# changed by passing DIRECTORY. The user can override through the
# --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR

View File

@@ -0,0 +1,35 @@
# valgrind-tests.m4 serial 2
dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Simon Josefsson
# gl_VALGRIND_TESTS()
# -------------------
# Check if valgrind is available, and set VALGRIND to it if available.
AC_DEFUN([gl_VALGRIND_TESTS],
[
AC_ARG_ENABLE(valgrind-tests,
AS_HELP_STRING([--enable-valgrind-tests],
[run self tests under valgrind]),
[opt_valgrind_tests=$enableval], [opt_valgrind_tests=no])
# Run self-tests under valgrind?
if test "$opt_valgrind_tests" = "yes" && test "$cross_compiling" = no; then
AC_CHECK_PROGS(VALGRIND, valgrind)
fi
if test -n "$VALGRIND" && $VALGRIND -q true > /dev/null 2>&1; then
opt_valgrind_tests=yes
VALGRIND="$VALGRIND -q --error-exitcode=1 --leak-check=full \
--trace-children=yes --trace-children-skip=/usr/*,/bin/*"
else
opt_valgrind_tests=no
VALGRIND=
fi
AC_MSG_CHECKING([whether self tests are run under valgrind])
AC_MSG_RESULT($opt_valgrind_tests)
])

View File

@@ -0,0 +1,13 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
bindir=@bindir@
Name: @PACKAGE_NAME@
Description: @PACKAGE_DESCRIPTION@
Version: @PACKAGE_VERSION@
URL: @PACKAGE_URL@
Libs: -L${libdir} -lprotobuf-c
Libs.private:
Cflags: -I${includedir}

View File

@@ -0,0 +1,28 @@
LIBPROTOBUF_C_1.0.0 {
global:
protobuf_c_buffer_simple_append;
protobuf_c_enum_descriptor_get_value;
protobuf_c_enum_descriptor_get_value_by_name;
protobuf_c_message_check;
protobuf_c_message_descriptor_get_field;
protobuf_c_message_descriptor_get_field_by_name;
protobuf_c_message_free_unpacked;
protobuf_c_message_get_packed_size;
protobuf_c_message_init;
protobuf_c_message_pack;
protobuf_c_message_pack_to_buffer;
protobuf_c_message_unpack;
protobuf_c_service_descriptor_get_method_by_name;
protobuf_c_service_destroy;
protobuf_c_service_generated_init;
protobuf_c_service_invoke_internal;
protobuf_c_version;
protobuf_c_version_number;
local:
*;
};
LIBPROTOBUF_C_1.3.0 {
global:
protobuf_c_empty_string;
} LIBPROTOBUF_C_1.0.0;

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 2021, the protobuf-c authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
syntax = "proto2";
import "google/protobuf/descriptor.proto";
// We never need to generate protobuf-c.pb-c.{c,h}, the options are used
// only by protoc-gen-c, never by the protobuf-c runtime itself
option (pb_c_file).no_generate = true;
message ProtobufCFileOptions {
// Suppresses pb-c.{c,h} file output completely.
optional bool no_generate = 1 [default = false];
// Generate helper pack/unpack functions?
// For backwards compatibility, if this field is not explicitly set,
// only top-level message pack/unpack functions will be generated
optional bool gen_pack_helpers = 2 [default = true];
// Generate helper init message functions?
optional bool gen_init_helpers = 3 [default = true];
// Use const char * instead of char * for string fields
optional bool const_strings = 4 [default = false];
// For oneof fields, set ProtobufCFieldDescriptor name field to the
// name of the containing oneof, instead of the field name
optional bool use_oneof_field_name = 5 [default = false];
// Overrides the package name, if present
optional string c_package = 6;
}
extend google.protobuf.FileOptions {
optional ProtobufCFileOptions pb_c_file = 1019;
}
message ProtobufCMessageOptions {
// Overrides the parent setting only if present
optional bool gen_pack_helpers = 1 [default = false];
// Overrides the parent setting only if present
optional bool gen_init_helpers = 2 [default = true];
// Reserved base message field name
optional string base_field_name = 3 [default = "base"];
}
extend google.protobuf.MessageOptions {
optional ProtobufCMessageOptions pb_c_msg = 1019;
}
message ProtobufCFieldOptions {
// Treat string as bytes in generated code
optional bool string_as_bytes = 1 [default = false];
}
extend google.protobuf.FieldOptions {
optional ProtobufCFieldOptions pb_c_field = 1019;
}

View File

@@ -0,0 +1,163 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_bytes_field.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <protobuf-c/protobuf-c.pb.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
using internal::WireFormat;
void SetBytesVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["default"] =
"\"" + CEscape(descriptor->default_value_string()) + "\"";
(*variables)["deprecated"] = FieldDeprecated(descriptor);
}
// ===================================================================
BytesFieldGenerator::
BytesFieldGenerator(const FieldDescriptor* descriptor)
: FieldGenerator(descriptor) {
SetBytesVariables(descriptor, &variables_);
variables_["default_value"] = descriptor->has_default_value()
? GetDefaultValue()
: std::string("{0,NULL}");
}
BytesFieldGenerator::~BytesFieldGenerator() {}
void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (descriptor_->containing_oneof() == NULL && FieldSyntax(descriptor_) == 2)
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(variables_, "ProtobufCBinaryData $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
printer->Print(variables_, "ProtobufCBinaryData *$name$$deprecated$;\n");
break;
}
}
void BytesFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data";
printer->Print(vars, "extern uint8_t $default_value_data$[];\n");
}
void BytesFieldGenerator::GenerateDefaultValueImplementations(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["default_value_data"] = FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data";
vars["escaped"] = CEscape(descriptor_->default_value_string());
printer->Print(vars, "uint8_t $default_value_data$[] = \"$escaped$\";\n");
}
std::string BytesFieldGenerator::GetDefaultValue(void) const
{
return "{ "
+ SimpleItoa(descriptor_->default_value_string().size())
+ ", "
+ FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value_data }";
}
void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(variables_, "$default_value$");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (FieldSyntax(descriptor_) == 2)
printer->Print(variables_, "0, ");
printer->Print(variables_, "$default_value$");
break;
case FieldDescriptor::LABEL_REPEATED:
// no support for default?
printer->Print("0,NULL");
break;
}
}
void BytesFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
GenerateDescriptorInitializerGeneric(printer, true, "BYTES", "NULL");
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,100 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_BYTES_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_BYTES_FIELD_H__
#include <map>
#include <string>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
class BytesFieldGenerator : public FieldGenerator {
public:
explicit BytesFieldGenerator(const FieldDescriptor* descriptor);
~BytesFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateDefaultValueDeclarations(io::Printer* printer) const;
void GenerateDefaultValueImplementations(io::Printer* printer) const;
std::string GetDefaultValue(void) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
std::map<std::string, std::string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BytesFieldGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__

View File

@@ -0,0 +1,334 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <set>
#include <map>
#include <protoc-c/c_enum.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
const std::string& dllexport_decl)
: descriptor_(descriptor),
dllexport_decl_(dllexport_decl) {
}
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name();
vars["uc_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
SourceLocation sourceLoc;
descriptor_->GetSourceLocation(&sourceLoc);
PrintComment (printer, sourceLoc.leading_comments);
printer->Print(vars, "typedef enum _$classname$ {\n");
printer->Indent();
const EnumValueDescriptor* min_value = descriptor_->value(0);
const EnumValueDescriptor* max_value = descriptor_->value(0);
vars["opt_comma"] = ",";
vars["prefix"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__";
for (int i = 0; i < descriptor_->value_count(); i++) {
vars["name"] = descriptor_->value(i)->name();
vars["number"] = SimpleItoa(descriptor_->value(i)->number());
if (i + 1 == descriptor_->value_count())
vars["opt_comma"] = "";
SourceLocation valSourceLoc;
descriptor_->value(i)->GetSourceLocation(&valSourceLoc);
PrintComment (printer, valSourceLoc.leading_comments);
PrintComment (printer, valSourceLoc.trailing_comments);
printer->Print(vars, "$prefix$$name$ = $number$$opt_comma$\n");
if (descriptor_->value(i)->number() < min_value->number()) {
min_value = descriptor_->value(i);
}
if (descriptor_->value(i)->number() > max_value->number()) {
max_value = descriptor_->value(i);
}
}
printer->Print(vars, " PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE($uc_name$)\n");
printer->Outdent();
printer->Print(vars, "} $classname$;\n");
}
void EnumGenerator::GenerateDescriptorDeclarations(io::Printer* printer) {
std::map<std::string, std::string> vars;
if (dllexport_decl_.empty()) {
vars["dllexport"] = "";
} else {
vars["dllexport"] = dllexport_decl_ + " ";
}
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
printer->Print(vars,
"extern $dllexport$const ProtobufCEnumDescriptor $lcclassname$__descriptor;\n");
}
struct ValueIndex
{
int value;
unsigned index;
unsigned final_index; /* index in uniqified array of values */
const char *name;
};
void EnumGenerator::GenerateValueInitializer(io::Printer *printer, int index)
{
const EnumValueDescriptor *vd = descriptor_->value(index);
std::map<std::string, std::string> vars;
bool optimize_code_size = descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE;
vars["enum_value_name"] = vd->name();
vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + vd->name();
vars["value"] = SimpleItoa(vd->number());
if (optimize_code_size)
printer->Print(vars, " { NULL, NULL, $value$ }, /* CODE_SIZE */\n");
else
printer->Print(vars,
" { \"$enum_value_name$\", \"$c_enum_value_name$\", $value$ },\n");
}
static int compare_value_indices_by_value_then_index(const void *a, const void *b)
{
const ValueIndex *vi_a = (const ValueIndex *) a;
const ValueIndex *vi_b = (const ValueIndex *) b;
if (vi_a->value < vi_b->value) return -1;
if (vi_a->value > vi_b->value) return +1;
if (vi_a->index < vi_b->index) return -1;
if (vi_a->index > vi_b->index) return +1;
return 0;
}
static int compare_value_indices_by_name(const void *a, const void *b)
{
const ValueIndex *vi_a = (const ValueIndex *) a;
const ValueIndex *vi_b = (const ValueIndex *) b;
return strcmp (vi_a->name, vi_b->name);
}
void EnumGenerator::GenerateEnumDescriptor(io::Printer* printer) {
std::map<std::string, std::string> vars;
vars["fullname"] = descriptor_->full_name();
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = descriptor_->name();
vars["packagename"] = descriptor_->file()->package();
vars["value_count"] = SimpleItoa(descriptor_->value_count());
bool optimize_code_size = descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE;
// Sort by name and value, dropping duplicate values if they appear later.
// TODO: use a c++ paradigm for this!
NameIndex *name_index = new NameIndex[descriptor_->value_count()];
ValueIndex *value_index = new ValueIndex[descriptor_->value_count()];
for (int j = 0; j < descriptor_->value_count(); j++) {
const EnumValueDescriptor *vd = descriptor_->value(j);
name_index[j].index = j;
name_index[j].name = vd->name().c_str();
value_index[j].index = j;
value_index[j].value = vd->number();
value_index[j].name = vd->name().c_str();
}
qsort(value_index, descriptor_->value_count(),
sizeof(ValueIndex), compare_value_indices_by_value_then_index);
// only record unique values
int n_unique_values;
if (descriptor_->value_count() == 0) {
n_unique_values = 0; // should never happen
} else {
n_unique_values = 1;
value_index[0].final_index = 0;
for (int j = 1; j < descriptor_->value_count(); j++) {
if (value_index[j-1].value != value_index[j].value)
value_index[j].final_index = n_unique_values++;
else
value_index[j].final_index = n_unique_values - 1;
}
}
vars["unique_value_count"] = SimpleItoa(n_unique_values);
printer->Print(vars,
"static const ProtobufCEnumValue $lcclassname$__enum_values_by_number[$unique_value_count$] =\n"
"{\n");
if (descriptor_->value_count() > 0) {
GenerateValueInitializer(printer, value_index[0].index);
for (int j = 1; j < descriptor_->value_count(); j++) {
if (value_index[j-1].value != value_index[j].value) {
GenerateValueInitializer(printer, value_index[j].index);
}
}
}
printer->Print(vars, "};\n");
printer->Print(vars, "static const ProtobufCIntRange $lcclassname$__value_ranges[] = {\n");
unsigned n_ranges = 0;
if (descriptor_->value_count() > 0) {
unsigned range_start = 0;
unsigned range_len = 1;
int range_start_value = value_index[0].value;
int last_value = range_start_value;
for (int j = 1; j < descriptor_->value_count(); j++) {
if (value_index[j-1].value != value_index[j].value) {
if (last_value + 1 == value_index[j].value) {
range_len++;
} else {
// output range
vars["range_start_value"] = SimpleItoa(range_start_value);
vars["orig_index"] = SimpleItoa(range_start);
printer->Print (vars, "{$range_start_value$, $orig_index$},");
range_start_value = value_index[j].value;
range_start += range_len;
range_len = 1;
n_ranges++;
}
last_value = value_index[j].value;
}
}
{
vars["range_start_value"] = SimpleItoa(range_start_value);
vars["orig_index"] = SimpleItoa(range_start);
printer->Print (vars, "{$range_start_value$, $orig_index$},");
range_start += range_len;
n_ranges++;
}
{
vars["range_start_value"] = SimpleItoa(0);
vars["orig_index"] = SimpleItoa(range_start);
printer->Print (vars, "{$range_start_value$, $orig_index$}\n};\n");
}
}
vars["n_ranges"] = SimpleItoa(n_ranges);
if (!optimize_code_size) {
qsort(value_index, descriptor_->value_count(),
sizeof(ValueIndex), compare_value_indices_by_name);
printer->Print(vars,
"static const ProtobufCEnumValueIndex $lcclassname$__enum_values_by_name[$value_count$] =\n"
"{\n");
for (int j = 0; j < descriptor_->value_count(); j++) {
vars["index"] = SimpleItoa(value_index[j].final_index);
vars["name"] = value_index[j].name;
printer->Print (vars, " { \"$name$\", $index$ },\n");
}
printer->Print(vars, "};\n");
}
if (optimize_code_size) {
printer->Print(vars,
"const ProtobufCEnumDescriptor $lcclassname$__descriptor =\n"
"{\n"
" PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,\n"
" NULL,NULL,NULL,NULL, /* CODE_SIZE */\n"
" $unique_value_count$,\n"
" $lcclassname$__enum_values_by_number,\n"
" 0, NULL, /* CODE_SIZE */\n"
" $n_ranges$,\n"
" $lcclassname$__value_ranges,\n"
" NULL,NULL,NULL,NULL /* reserved[1234] */\n"
"};\n");
} else {
printer->Print(vars,
"const ProtobufCEnumDescriptor $lcclassname$__descriptor =\n"
"{\n"
" PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC,\n"
" \"$fullname$\",\n"
" \"$shortname$\",\n"
" \"$cname$\",\n"
" \"$packagename$\",\n"
" $unique_value_count$,\n"
" $lcclassname$__enum_values_by_number,\n"
" $value_count$,\n"
" $lcclassname$__enum_values_by_name,\n"
" $n_ranges$,\n"
" $lcclassname$__value_ranges,\n"
" NULL,NULL,NULL,NULL /* reserved[1234] */\n"
"};\n");
}
delete[] value_index;
delete[] name_index;
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,118 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__
#define GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__
#include <string>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
class EnumGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit EnumGenerator(const EnumDescriptor* descriptor,
const std::string& dllexport_decl);
~EnumGenerator();
// Header stuff.
// Generate header code defining the enum. This code should be placed
// within the enum's package namespace, but NOT within any class, even for
// nested enums.
void GenerateDefinition(io::Printer* printer);
void GenerateDescriptorDeclarations(io::Printer* printer);
// Source file stuff.
// Generate the ProtobufCEnumDescriptor for this enum
void GenerateEnumDescriptor(io::Printer* printer);
// Generate static initializer for a ProtobufCEnumValue
// given the index of the value in the enum.
void GenerateValueInitializer(io::Printer *printer, int index);
private:
const EnumDescriptor* descriptor_;
std::string dllexport_decl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_ENUM_H__

View File

@@ -0,0 +1,149 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_enum_field.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
using internal::WireFormat;
// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of
// repeat code between this and the other field types.
void SetEnumVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file());
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
(*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file())
+ "__" + default_value->name();
(*variables)["deprecated"] = FieldDeprecated(descriptor);
}
// ===================================================================
EnumFieldGenerator::
EnumFieldGenerator(const FieldDescriptor* descriptor)
: FieldGenerator(descriptor)
{
SetEnumVariables(descriptor, &variables_);
}
EnumFieldGenerator::~EnumFieldGenerator() {}
void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(variables_, "$type$ $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (descriptor_->containing_oneof() == NULL && FieldSyntax(descriptor_) == 2)
printer->Print(variables_, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(variables_, "$type$ $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
printer->Print(variables_, "$type$ *$name$$deprecated$;\n");
break;
}
}
std::string EnumFieldGenerator::GetDefaultValue(void) const
{
return variables_.find("default")->second;
}
void EnumFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(variables_, "$default$");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (FieldSyntax(descriptor_) == 2)
printer->Print(variables_, "0, ");
printer->Print(variables_, "$default$");
break;
case FieldDescriptor::LABEL_REPEATED:
// no support for default?
printer->Print("0,NULL");
break;
}
}
void EnumFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
std::string addr = "&" + FullNameToLower(descriptor_->enum_type()->full_name(), descriptor_->enum_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, true, "ENUM", addr);
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,98 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__
#include <map>
#include <string>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
class EnumFieldGenerator : public FieldGenerator {
public:
explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
~EnumFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
std::string GetDefaultValue(void) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
std::map<std::string, std::string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_ENUM_FIELD_H__

View File

@@ -0,0 +1,90 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_extension.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
const std::string& dllexport_decl)
: descriptor_(descriptor),
dllexport_decl_(dllexport_decl) {
}
ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
}
void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,110 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_EXTENSION_H__
#define GOOGLE_PROTOBUF_COMPILER_C_EXTENSION_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
class FieldDescriptor; // descriptor.h
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
// Generates code for an extension, which may be within the scope of some
// message or may be at file scope. This is much simpler than FieldGenerator
// since extensions are just simple identifiers with interesting types.
class ExtensionGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ExtensionGenerator(const FieldDescriptor* descriptor,
const std::string& dllexport_decl);
~ExtensionGenerator();
// Header stuff.
void GenerateDeclaration(io::Printer* printer);
// Source file stuff.
void GenerateDefinition(io::Printer* printer);
private:
const FieldDescriptor* descriptor_;
std::string type_traits_;
std::string dllexport_decl_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__

View File

@@ -0,0 +1,241 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_field.h>
#include <protoc-c/c_primitive_field.h>
#include <protoc-c/c_string_field.h>
#include <protoc-c/c_bytes_field.h>
#include <protoc-c/c_enum_field.h>
#include <protoc-c/c_message_field.h>
#include <protoc-c/c_helpers.h>
#include <protobuf-c/protobuf-c.pb.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
FieldGenerator::~FieldGenerator()
{
}
static bool is_packable_type(FieldDescriptor::Type type)
{
return type == FieldDescriptor::TYPE_DOUBLE
|| type == FieldDescriptor::TYPE_FLOAT
|| type == FieldDescriptor::TYPE_INT64
|| type == FieldDescriptor::TYPE_UINT64
|| type == FieldDescriptor::TYPE_INT32
|| type == FieldDescriptor::TYPE_FIXED64
|| type == FieldDescriptor::TYPE_FIXED32
|| type == FieldDescriptor::TYPE_BOOL
|| type == FieldDescriptor::TYPE_UINT32
|| type == FieldDescriptor::TYPE_ENUM
|| type == FieldDescriptor::TYPE_SFIXED32
|| type == FieldDescriptor::TYPE_SFIXED64
|| type == FieldDescriptor::TYPE_SINT32
|| type == FieldDescriptor::TYPE_SINT64;
//TYPE_BYTES
//TYPE_STRING
//TYPE_GROUP
//TYPE_MESSAGE
}
void FieldGenerator::GenerateDescriptorInitializerGeneric(io::Printer* printer,
bool optional_uses_has,
const std::string &type_macro,
const std::string &descriptor_addr) const
{
std::map<std::string, std::string> variables;
const OneofDescriptor *oneof = descriptor_->containing_oneof();
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
variables["TYPE"] = type_macro;
variables["classname"] = FullNameToC(FieldScope(descriptor_)->full_name(), FieldScope(descriptor_)->file());
variables["name"] = FieldName(descriptor_);
if (opt.use_oneof_field_name())
variables["proto_name"] = oneof->name();
else
variables["proto_name"] = descriptor_->name();
variables["descriptor_addr"] = descriptor_addr;
variables["value"] = SimpleItoa(descriptor_->number());
if (oneof != NULL)
variables["oneofname"] = CamelToLower(oneof->name());
if (FieldSyntax(descriptor_) == 3 &&
descriptor_->label() == FieldDescriptor::LABEL_OPTIONAL) {
variables["LABEL"] = "NONE";
optional_uses_has = false;
} else {
variables["LABEL"] = CamelToUpper(GetLabelName(descriptor_->label()));
}
if (descriptor_->has_default_value()) {
variables["default_value"] = std::string("&")
+ FullNameToLower(descriptor_->full_name(), descriptor_->file())
+ "__default_value";
} else if (FieldSyntax(descriptor_) == 3 &&
descriptor_->type() == FieldDescriptor::TYPE_STRING) {
variables["default_value"] = "&protobuf_c_empty_string";
} else {
variables["default_value"] = "NULL";
}
variables["flags"] = "0";
if (descriptor_->label() == FieldDescriptor::LABEL_REPEATED
&& is_packable_type (descriptor_->type())
&& descriptor_->options().packed()) {
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_PACKED";
} else if (descriptor_->label() == FieldDescriptor::LABEL_REPEATED
&& is_packable_type (descriptor_->type())
&& FieldSyntax(descriptor_) == 3
&& !descriptor_->options().has_packed()) {
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_PACKED";
}
if (descriptor_->options().deprecated())
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_DEPRECATED";
if (oneof != NULL)
variables["flags"] += " | PROTOBUF_C_FIELD_FLAG_ONEOF";
printer->Print("{\n");
if (descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE) {
printer->Print(" NULL, /* CODE_SIZE */\n");
} else {
printer->Print(variables, " \"$proto_name$\",\n");
}
printer->Print(variables,
" $value$,\n"
" PROTOBUF_C_LABEL_$LABEL$,\n"
" PROTOBUF_C_TYPE_$TYPE$,\n");
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(variables, " 0, /* quantifier_offset */\n");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (oneof != NULL) {
printer->Print(variables, " offsetof($classname$, $oneofname$_case),\n");
} else if (optional_uses_has) {
printer->Print(variables, " offsetof($classname$, has_$name$),\n");
} else {
printer->Print(variables, " 0, /* quantifier_offset */\n");
}
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables, " offsetof($classname$, n_$name$),\n");
break;
}
printer->Print(variables, " offsetof($classname$, $name$),\n");
printer->Print(variables, " $descriptor_addr$,\n");
printer->Print(variables, " $default_value$,\n");
printer->Print(variables, " $flags$, /* flags */\n");
printer->Print(variables, " 0,NULL,NULL /* reserved1,reserved2, etc */\n");
printer->Print("},\n");
}
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
: descriptor_(descriptor),
field_generators_(
new std::unique_ptr<FieldGenerator>[descriptor->field_count()]) {
// Construct all the FieldGenerators.
for (int i = 0; i < descriptor->field_count(); i++) {
field_generators_[i].reset(MakeGenerator(descriptor->field(i)));
}
}
FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) {
const ProtobufCFieldOptions opt = field->options().GetExtension(pb_c_field);
switch (field->type()) {
case FieldDescriptor::TYPE_MESSAGE:
return new MessageFieldGenerator(field);
case FieldDescriptor::TYPE_STRING:
if (opt.string_as_bytes())
return new BytesFieldGenerator(field);
else
return new StringFieldGenerator(field);
case FieldDescriptor::TYPE_BYTES:
return new BytesFieldGenerator(field);
case FieldDescriptor::TYPE_ENUM:
return new EnumFieldGenerator(field);
case FieldDescriptor::TYPE_GROUP:
return 0; // XXX
default:
return new PrimitiveFieldGenerator(field);
}
}
FieldGeneratorMap::~FieldGeneratorMap() {}
const FieldGenerator& FieldGeneratorMap::get(
const FieldDescriptor* field) const {
GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
return *field_generators_[field->index()];
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,133 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__
#include <memory>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
class FieldGenerator {
public:
explicit FieldGenerator(const FieldDescriptor *descriptor) : descriptor_(descriptor) {}
virtual ~FieldGenerator();
// Generate definitions to be included in the structure.
virtual void GenerateStructMembers(io::Printer* printer) const = 0;
// Generate a static initializer for this field.
virtual void GenerateDescriptorInitializer(io::Printer* printer) const = 0;
virtual void GenerateDefaultValueDeclarations(io::Printer* printer) const { }
virtual void GenerateDefaultValueImplementations(io::Printer* printer) const { }
virtual std::string GetDefaultValue() const = 0;
// Generate members to initialize this field from a static initializer
virtual void GenerateStaticInit(io::Printer* printer) const = 0;
protected:
void GenerateDescriptorInitializerGeneric(io::Printer* printer,
bool optional_uses_has,
const std::string &type_macro,
const std::string &descriptor_addr) const;
const FieldDescriptor *descriptor_;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
};
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
explicit FieldGeneratorMap(const Descriptor* descriptor);
~FieldGeneratorMap();
const FieldGenerator& get(const FieldDescriptor* field) const;
private:
const Descriptor* descriptor_;
std::unique_ptr<std::unique_ptr<FieldGenerator>[]> field_generators_;
static FieldGenerator* MakeGenerator(const FieldDescriptor* field);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_FIELD_H__

View File

@@ -0,0 +1,274 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_file.h>
#include <protoc-c/c_enum.h>
#include <protoc-c/c_service.h>
#include <protoc-c/c_extension.h>
#include <protoc-c/c_helpers.h>
#include <protoc-c/c_message.h>
#include <google/protobuf/io/printer.h>
#include <protobuf-c/protobuf-c.pb.h>
#include "protobuf-c.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
// ===================================================================
FileGenerator::FileGenerator(const FileDescriptor* file,
const std::string& dllexport_decl)
: file_(file),
message_generators_(
new std::unique_ptr<MessageGenerator>[file->message_type_count()]),
enum_generators_(
new std::unique_ptr<EnumGenerator>[file->enum_type_count()]),
service_generators_(
new std::unique_ptr<ServiceGenerator>[file->service_count()]),
extension_generators_(
new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) {
for (int i = 0; i < file->message_type_count(); i++) {
message_generators_[i].reset(
new MessageGenerator(file->message_type(i), dllexport_decl));
}
for (int i = 0; i < file->enum_type_count(); i++) {
enum_generators_[i].reset(
new EnumGenerator(file->enum_type(i), dllexport_decl));
}
for (int i = 0; i < file->service_count(); i++) {
service_generators_[i].reset(
new ServiceGenerator(file->service(i), dllexport_decl));
}
for (int i = 0; i < file->extension_count(); i++) {
extension_generators_[i].reset(
new ExtensionGenerator(file->extension(i), dllexport_decl));
}
}
FileGenerator::~FileGenerator() {}
void FileGenerator::GenerateHeader(io::Printer* printer) {
std::string filename_identifier = FilenameIdentifier(file_->name());
int min_header_version = 1000000;
#if defined(HAVE_PROTO3)
if (file_->syntax() == FileDescriptor::SYNTAX_PROTO3) {
min_header_version = 1003000;
}
#endif
// Generate top of header.
printer->Print(
"/* Generated by the protocol buffer compiler. DO NOT EDIT! */\n"
"/* Generated from: $filename$ */\n"
"\n"
"#ifndef PROTOBUF_C_$filename_identifier$__INCLUDED\n"
"#define PROTOBUF_C_$filename_identifier$__INCLUDED\n"
"\n"
"#include <protobuf-c/protobuf-c.h>\n"
"\n"
"PROTOBUF_C__BEGIN_DECLS\n"
"\n",
"filename", file_->name(),
"filename_identifier", filename_identifier);
// Verify the protobuf-c library header version is compatible with the
// protoc-c version before going any further.
printer->Print(
"#if PROTOBUF_C_VERSION_NUMBER < $min_header_version$\n"
"# error This file was generated by a newer version of protoc-c which is "
"incompatible with your libprotobuf-c headers. Please update your headers.\n"
"#elif $protoc_version$ < PROTOBUF_C_MIN_COMPILER_VERSION\n"
"# error This file was generated by an older version of protoc-c which is "
"incompatible with your libprotobuf-c headers. Please regenerate this file "
"with a newer version of protoc-c.\n"
"#endif\n"
"\n",
"min_header_version", SimpleItoa(min_header_version),
"protoc_version", SimpleItoa(PROTOBUF_C_VERSION_NUMBER));
for (int i = 0; i < file_->dependency_count(); i++) {
const ProtobufCFileOptions opt =
file_->dependency(i)->options().GetExtension(pb_c_file);
if (!opt.no_generate()) {
printer->Print(
"#include \"$dependency$.pb-c.h\"\n",
"dependency", StripProto(file_->dependency(i)->name()));
}
}
printer->Print("\n");
// Generate forward declarations of classes.
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateStructTypedef(printer);
}
printer->Print("\n");
// Generate enum definitions.
printer->Print("\n/* --- enums --- */\n\n");
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateEnumDefinitions(printer);
}
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDefinition(printer);
}
// Generate class definitions.
printer->Print("\n/* --- messages --- */\n\n");
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateStructDefinition(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
const ProtobufCFileOptions opt = file_->options().GetExtension(pb_c_file);
message_generators_[i]->GenerateHelperFunctionDeclarations(
printer,
opt.has_gen_pack_helpers(),
opt.gen_pack_helpers(),
opt.gen_init_helpers());
}
printer->Print("/* --- per-message closures --- */\n\n");
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateClosureTypedef(printer);
}
// Generate service definitions.
printer->Print("\n/* --- services --- */\n\n");
for (int i = 0; i < file_->service_count(); i++) {
service_generators_[i]->GenerateMainHFile(printer);
}
// Declare extension identifiers.
for (int i = 0; i < file_->extension_count(); i++) {
extension_generators_[i]->GenerateDeclaration(printer);
}
printer->Print("\n/* --- descriptors --- */\n\n");
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDescriptorDeclarations(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateDescriptorDeclarations(printer);
}
for (int i = 0; i < file_->service_count(); i++) {
service_generators_[i]->GenerateDescriptorDeclarations(printer);
}
printer->Print(
"\n"
"PROTOBUF_C__END_DECLS\n"
"\n\n#endif /* PROTOBUF_C_$filename_identifier$__INCLUDED */\n",
"filename_identifier", filename_identifier);
}
void FileGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"/* Generated by the protocol buffer compiler. DO NOT EDIT! */\n"
"/* Generated from: $filename$ */\n"
"\n"
"/* Do not generate deprecated warnings for self */\n"
"#ifndef PROTOBUF_C__NO_DEPRECATED\n"
"#define PROTOBUF_C__NO_DEPRECATED\n"
"#endif\n"
"\n"
"#include \"$basename$.pb-c.h\"\n",
"filename", file_->name(),
"basename", StripProto(file_->name()));
const ProtobufCFileOptions opt = file_->options().GetExtension(pb_c_file);
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateHelperFunctionDefinitions(
printer,
opt.has_gen_pack_helpers(),
opt.gen_pack_helpers(),
opt.gen_init_helpers());
}
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateMessageDescriptor(printer,
opt.gen_init_helpers());
}
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateEnumDescriptor(printer);
}
for (int i = 0; i < file_->service_count(); i++) {
service_generators_[i]->GenerateCFile(printer);
}
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,115 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_FILE_H__
#define GOOGLE_PROTOBUF_COMPILER_C_FILE_H__
#include <memory>
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
class FileDescriptor; // descriptor.h
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
class EnumGenerator; // enum.h
class MessageGenerator; // message.h
class ServiceGenerator; // service.h
class ExtensionGenerator; // extension.h
class FileGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit FileGenerator(const FileDescriptor* file,
const std::string& dllexport_decl);
~FileGenerator();
void GenerateHeader(io::Printer* printer);
void GenerateSource(io::Printer* printer);
private:
const FileDescriptor* file_;
std::unique_ptr<std::unique_ptr<MessageGenerator>[]> message_generators_;
std::unique_ptr<std::unique_ptr<EnumGenerator>[]> enum_generators_;
std::unique_ptr<std::unique_ptr<ServiceGenerator>[]> service_generators_;
std::unique_ptr<std::unique_ptr<ExtensionGenerator>[]> extension_generators_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_FILE_H__

View File

@@ -0,0 +1,176 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_generator.h>
#include <memory>
#include <vector>
#include <utility>
#include <protoc-c/c_file.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <protobuf-c/protobuf-c.pb.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
// Parses a set of comma-delimited name/value pairs, e.g.:
// "foo=bar,baz,qux=corge"
// parses to the pairs:
// ("foo", "bar"), ("baz", ""), ("qux", "corge")
void ParseOptions(const std::string& text, std::vector<std::pair<std::string, std::string> >* output) {
std::vector<std::string> parts;
SplitStringUsing(text, ",", &parts);
for (unsigned i = 0; i < parts.size(); i++) {
std::string::size_type equals_pos = parts[i].find_first_of('=');
std::pair<std::string, std::string> value;
if (equals_pos == std::string::npos) {
value.first = parts[i];
value.second = "";
} else {
value.first = parts[i].substr(0, equals_pos);
value.second = parts[i].substr(equals_pos + 1);
}
output->push_back(value);
}
}
CGenerator::CGenerator() {}
CGenerator::~CGenerator() {}
bool CGenerator::Generate(const FileDescriptor* file,
const std::string& parameter,
OutputDirectory* output_directory,
std::string* error) const {
if (file->options().GetExtension(pb_c_file).no_generate())
return true;
std::vector<std::pair<std::string, std::string> > options;
ParseOptions(parameter, &options);
// -----------------------------------------------------------------
// parse generator options
// TODO(kenton): If we ever have more options, we may want to create a
// class that encapsulates them which we can pass down to all the
// generator classes. Currently we pass dllexport_decl down to all of
// them via the constructors, but we don't want to have to add another
// constructor parameter for every option.
// If the dllexport_decl option is passed to the compiler, we need to write
// it in front of every symbol that should be exported if this .proto is
// compiled into a Windows DLL. E.g., if the user invokes the protocol
// compiler as:
// protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
// then we'll define classes like this:
// class FOO_EXPORT Foo {
// ...
// }
// FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
// __declspec(dllimport) depending on what is being compiled.
std::string dllexport_decl;
for (unsigned i = 0; i < options.size(); i++) {
if (options[i].first == "dllexport_decl") {
dllexport_decl = options[i].second;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
}
}
// -----------------------------------------------------------------
std::string basename = StripProto(file->name());
basename.append(".pb-c");
FileGenerator file_generator(file, dllexport_decl);
// Generate header.
{
std::unique_ptr<io::ZeroCopyOutputStream> output(
output_directory->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
file_generator.GenerateHeader(&printer);
}
// Generate cc file.
{
std::unique_ptr<io::ZeroCopyOutputStream> output(
output_directory->Open(basename + ".c"));
io::Printer printer(output.get(), '$');
file_generator.GenerateSource(&printer);
}
return true;
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,106 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
// Generates C code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
# define PROTOC_C_EXPORT __declspec(dllexport)
#else
# define PROTOC_C_EXPORT
#endif
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
// CodeGenerator implementation which generates a C++ source file and
// header. If you create your own protocol compiler binary and you want
// it to support C++ output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_C_EXPORT CGenerator : public CodeGenerator {
public:
CGenerator();
~CGenerator();
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file,
const std::string& parameter,
OutputDirectory* output_directory,
std::string* error) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_GENERATOR_H__

View File

@@ -0,0 +1,558 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <memory>
#include <vector>
#include <set>
#include <stdio.h> // for snprintf
#include <float.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
#if defined(_MSC_VER)
// FIXME: In the case where the generated string is longer than the buffer,
// _snprint() returns a negative value, where snprintf() returns the number
// of characters that *would* have been stored, had there been room.
// That is fundamental, as it allows snprintf() to be used to find the size
// necessary for the buffer, simply by calling it with the size of the buffer
// passed in as zero.
// Note: at the present moment return value isn't used in the code.
#define snprintf _snprintf
#pragma warning(disable:4800)
#pragma warning(disable:4996)
#endif
std::string DotsToUnderscores(const std::string& name) {
return StringReplace(name, ".", "_", true);
}
std::string DotsToColons(const std::string& name) {
return StringReplace(name, ".", "::", true);
}
std::string SimpleFtoa(float f) {
char buf[100];
snprintf(buf,sizeof(buf),"%.*g", FLT_DIG, f);
buf[sizeof(buf)-1] = 0; /* should NOT be necessary */
return buf;
}
std::string SimpleDtoa(double d) {
char buf[100];
snprintf(buf,sizeof(buf),"%.*g", DBL_DIG, d);
buf[sizeof(buf)-1] = 0; /* should NOT be necessary */
return buf;
}
std::string CamelToUpper(const std::string &name) {
bool was_upper = true; // suppress initial _
std::string rv = "";
int len = name.length();
for (int i = 0; i < len; i++) {
bool is_upper = isupper(name[i]);
if (is_upper) {
if (!was_upper)
rv += '_';
rv += name[i];
} else {
rv += toupper(name[i]);
}
was_upper = is_upper;
}
return rv;
}
std::string CamelToLower(const std::string &name) {
bool was_upper = true; // suppress initial _
std::string rv = "";
int len = name.length();
for (int i = 0; i < len; i++) {
bool is_upper = isupper(name[i]);
if (is_upper) {
if (!was_upper)
rv += '_';
rv += tolower(name[i]);
} else {
rv += name[i];
}
was_upper = is_upper;
}
return rv;
}
std::string ToUpper(const std::string &name) {
std::string rv = "";
int len = name.length();
for (int i = 0; i < len; i++) {
rv += toupper(name[i]);
}
return rv;
}
std::string ToLower(const std::string &name) {
std::string rv = "";
int len = name.length();
for (int i = 0; i < len; i++) {
rv += tolower(name[i]);
}
return rv;
}
std::string ToCamel(const std::string &name) {
std::string rv = "";
int len = name.length();
bool next_is_upper = true;
for (int i = 0; i < len; i++) {
if (name[i] == '_') {
next_is_upper = true;
} else if (next_is_upper) {
rv += toupper (name[i]);
next_is_upper = false;
} else {
rv += name[i];
}
}
return rv;
}
std::string OverrideFullName(const std::string &full_name,
const FileDescriptor *file) {
const ProtobufCFileOptions opt = file->options().GetExtension(pb_c_file);
if (!opt.has_c_package())
return full_name;
std::string new_name = opt.c_package();
if (file->package().empty())
new_name += ".";
return new_name + full_name.substr(file->package().length());
}
std::string FullNameToLower(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;
if (rv != "") rv += "__";
rv += CamelToLower(pieces[i]);
}
return rv;
}
std::string FullNameToUpper(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;
if (rv != "") rv += "__";
rv += CamelToUpper(pieces[i]);
}
return rv;
}
std::string FullNameToC(const std::string &full_name,
const FileDescriptor *file) {
std::vector<std::string> pieces;
SplitStringUsing(OverrideFullName(full_name, file), ".", &pieces);
std::string rv = "";
for (unsigned i = 0; i < pieces.size(); i++) {
if (pieces[i] == "") continue;
if (rv != "") rv += "__";
rv += ToCamel(pieces[i]);
}
return rv;
}
void PrintComment (io::Printer* printer, std::string comment)
{
if (!comment.empty())
{
std::vector<std::string> comment_lines;
SplitStringUsing (comment, "\r\n", &comment_lines);
printer->Print ("/*\n");
for (int i = 0; i < comment_lines.size(); i++)
{
if (!comment_lines[i].empty())
{
/* Make sure we don't inadvertently close the comment block */
if (comment_lines[i][0] == '/')
comment_lines[i] = ' ' + comment_lines[i];
/* Or cause other compiler issues. */
size_t delim_i;
while ((delim_i = comment_lines[i].find("/*")) != std::string::npos)
comment_lines[i][delim_i] = ' ';
while ((delim_i = comment_lines[i].find("*/")) != std::string::npos)
comment_lines[i][delim_i + 1] = ' ';
printer->Print (" *$line$\n", "line", comment_lines[i]);
}
}
printer->Print (" */\n");
}
}
std::string ConvertToSpaces(const std::string &input) {
return std::string(input.size(), ' ');
}
int compare_name_indices_by_name(const void *a, const void *b)
{
const NameIndex *ni_a = (const NameIndex *) a;
const NameIndex *ni_b = (const NameIndex *) b;
return strcmp (ni_a->name, ni_b->name);
}
std::string CEscape(const std::string& src);
const char* const kKeywordList[] = {
"and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
"catch", "char", "class", "compl", "const", "const_cast", "continue",
"default", "delete", "do", "double", "dynamic_cast", "else", "enum",
"explicit", "extern", "false", "float", "for", "friend", "goto", "if",
"inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
"operator", "or", "or_eq", "private", "protected", "public", "register",
"reinterpret_cast", "return", "short", "signed", "sizeof", "static",
"static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
"typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
"void", "volatile", "wchar_t", "while", "xor", "xor_eq"
};
std::set<std::string> MakeKeywordsMap() {
std::set<std::string> result;
for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
result.insert(kKeywordList[i]);
}
return result;
}
std::set<std::string> kKeywords = MakeKeywordsMap();
std::string FieldName(const FieldDescriptor* field) {
std::string result = ToLower(field->name());
if (kKeywords.count(result) > 0) {
result.append("_");
}
return result;
}
std::string FieldDeprecated(const FieldDescriptor* field) {
if (field->options().deprecated()) {
return " PROTOBUF_C__DEPRECATED";
}
return "";
}
std::string StripProto(const std::string& filename) {
if (HasSuffixString(filename, ".protodevel")) {
return StripSuffixString(filename, ".protodevel");
} else {
return StripSuffixString(filename, ".proto");
}
}
// Convert a file name into a valid identifier.
std::string FilenameIdentifier(const std::string& filename) {
std::string result;
for (unsigned i = 0; i < filename.size(); i++) {
if (isalnum(filename[i])) {
result.push_back(filename[i]);
} else {
// Not alphanumeric. To avoid any possibility of name conflicts we
// use the hex code for the character.
result.push_back('_');
char buffer[32];
result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
}
}
return result;
}
// Return the name of the BuildDescriptors() function for a given file.
std::string GlobalBuildDescriptorsName(const std::string& filename) {
return "proto_BuildDescriptors_" + FilenameIdentifier(filename);
}
std::string GetLabelName(FieldDescriptor::Label label) {
switch (label) {
case FieldDescriptor::LABEL_OPTIONAL: return "optional";
case FieldDescriptor::LABEL_REQUIRED: return "required";
case FieldDescriptor::LABEL_REPEATED: return "repeated";
}
return "bad-label";
}
unsigned
WriteIntRanges(io::Printer* printer, int n_values, const int *values, const std::string &name)
{
std::map<std::string, std::string> vars;
vars["name"] = name;
if (n_values > 0) {
int n_ranges = 1;
for (int i = 1; i < n_values; i++) {
if (values[i-1] + 1 != values[i])
n_ranges++;
}
vars["n_ranges"] = SimpleItoa(n_ranges);
printer->Print(vars, "static const ProtobufCIntRange $name$[$n_ranges$ + 1] =\n"
"{\n");
int last_range_start = 0;
for (int i = 1; i < n_values; i++) {
if (values[i-1] + 1 != values[i]) {
int count = i - last_range_start;
int expected = values[i-1] + 1;
vars["start_value"] = SimpleItoa(expected - count);
vars["orig_offset"] = SimpleItoa(last_range_start);
printer->Print (vars, " { $start_value$, $orig_offset$ },\n");
last_range_start = i;
}
}
// write last real entry
{
int i = n_values;
int count = i - last_range_start;
int expected = values[i-1] + 1;
vars["start_value"] = SimpleItoa(expected - count);
vars["orig_offset"] = SimpleItoa(last_range_start);
printer->Print (vars, " { $start_value$, $orig_offset$ },\n");
}
// write sentinel entry
vars["n_entries"] = SimpleItoa(n_values);
printer->Print (vars, " { 0, $n_entries$ }\n");
printer->Print (vars, "};\n");
return n_ranges;
} else {
printer->Print (vars, "#define $name$ NULL\n");
return 0;
}
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
// XXXXXXXXX this stuff is copied from strutils.cc !!!! XXXXXXXXXXXXXXXXXXXXXXXXXXXXx
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
// ----------------------------------------------------------------------
// StringReplace()
// Replace the "old" pattern with the "new" pattern in a string,
// and append the result to "res". If replace_all is false,
// it only replaces the first instance of "old."
// ----------------------------------------------------------------------
void StringReplace(const std::string& s, const std::string& oldsub,
const std::string& newsub, bool replace_all,
std::string* res) {
if (oldsub.empty()) {
res->append(s); // if empty, append the given string.
return;
}
std::string::size_type start_pos = 0;
std::string::size_type pos;
do {
pos = s.find(oldsub, start_pos);
if (pos == std::string::npos) {
break;
}
res->append(s, start_pos, pos - start_pos);
res->append(newsub);
start_pos = pos + oldsub.size(); // start searching again after the "old"
} while (replace_all);
res->append(s, start_pos, s.length() - start_pos);
}
// ----------------------------------------------------------------------
// StringReplace()
// Give me a string and two patterns "old" and "new", and I replace
// the first instance of "old" in the string with "new", if it
// exists. If "global" is true; call this repeatedly until it
// fails. RETURN a new string, regardless of whether the replacement
// happened or not.
// ----------------------------------------------------------------------
std::string StringReplace(const std::string& s, const std::string& oldsub,
const std::string& newsub, bool replace_all) {
std::string ret;
StringReplace(s, oldsub, newsub, replace_all, &ret);
return ret;
}
// ----------------------------------------------------------------------
// SplitStringUsing()
// Split a string using a character delimiter. Append the components
// to 'result'.
//
// Note: For multi-character delimiters, this routine will split on *ANY* of
// the characters in the string, not the entire string as a single delimiter.
// ----------------------------------------------------------------------
template <typename ITR>
static inline
void SplitStringToIteratorUsing(const std::string& full,
const char* delim,
ITR& result) {
// Optimize the common case where delim is a single character.
if (delim[0] != '\0' && delim[1] == '\0') {
char c = delim[0];
const char* p = full.data();
const char* end = p + full.size();
while (p != end) {
if (*p == c) {
++p;
} else {
const char* start = p;
while (++p != end && *p != c);
*result++ = std::string(start, p - start);
}
}
return;
}
std::string::size_type begin_index, end_index;
begin_index = full.find_first_not_of(delim);
while (begin_index != std::string::npos) {
end_index = full.find_first_of(delim, begin_index);
if (end_index == std::string::npos) {
*result++ = full.substr(begin_index);
return;
}
*result++ = full.substr(begin_index, (end_index - begin_index));
begin_index = full.find_first_not_of(delim, end_index);
}
}
void SplitStringUsing(const std::string& full,
const char* delim,
std::vector<std::string>* result) {
std::back_insert_iterator< std::vector<std::string> > it(*result);
SplitStringToIteratorUsing(full, delim, it);
}
char* FastHexToBuffer(int i, char* buffer)
{
snprintf(buffer, 16, "%x", i);
return buffer;
}
static int CEscapeInternal(const char* src, int src_len, char* dest,
int dest_len, bool use_hex) {
const char* src_end = src + src_len;
int used = 0;
bool last_hex_escape = false; // true if last output char was \xNN
for (; src < src_end; src++) {
if (dest_len - used < 2) // Need space for two letter escape
return -1;
bool is_hex_escape = false;
switch (*src) {
case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break;
case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break;
case '\t': dest[used++] = '\\'; dest[used++] = 't'; break;
case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
default:
// Note that if we emit \xNN and the src character after that is a hex
// digit then that digit must be escaped too to prevent it being
// interpreted as part of the character code by C.
if (!isprint(*src) || (last_hex_escape && isxdigit(*src))) {
if (dest_len - used < 4) // need space for 4 letter escape
return -1;
sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
static_cast<uint8>(*src));
is_hex_escape = use_hex;
used += 4;
} else {
dest[used++] = *src; break;
}
}
last_hex_escape = is_hex_escape;
}
if (dest_len - used < 1) // make sure that there is room for \0
return -1;
dest[used] = '\0'; // doesn't count towards return value though
return used;
}
std::string CEscape(const std::string& src) {
const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
std::unique_ptr<char[]> dest(new char[dest_length]);
const int len = CEscapeInternal(src.data(), src.size(),
dest.get(), dest_length, false);
GOOGLE_DCHECK_GE(len, 0);
return std::string(dest.get(), len);
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,186 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__
#include <string>
#include <vector>
#include <sstream>
#include <google/protobuf/descriptor.h>
#include <protobuf-c/protobuf-c.pb.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
// --- Borrowed from stubs. ---
template <typename T> std::string SimpleItoa(T n) {
std::stringstream stream;
stream << n;
return stream.str();
}
std::string SimpleFtoa(float f);
std::string SimpleDtoa(double f);
void SplitStringUsing(const std::string &str, const char *delim, std::vector<std::string> *out);
std::string CEscape(const std::string& src);
std::string StringReplace(const std::string& s, const std::string& oldsub, const std::string& newsub, bool replace_all);
inline bool HasSuffixString(const std::string& str, const std::string& suffix) { return str.size() >= suffix.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; }
inline std::string StripSuffixString(const std::string& str, const std::string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { return str; } }
char* FastHexToBuffer(int i, char* buffer);
// Get the (unqualified) name that should be used for this field in C code.
// The name is coerced to lower-case to emulate proto1 behavior. People
// should be using lowercase-with-underscores style for proto field names
// anyway, so normally this just returns field->name().
std::string FieldName(const FieldDescriptor* field);
// Get macro string for deprecated field
std::string FieldDeprecated(const FieldDescriptor* field);
// Returns the scope where the field was defined (for extensions, this is
// different from the message type to which the field applies).
inline const Descriptor* FieldScope(const FieldDescriptor* field) {
return field->is_extension() ?
field->extension_scope() : field->containing_type();
}
// convert a CamelCase class name into an all uppercase affair
// with underscores separating words, e.g. MyClass becomes MY_CLASS.
std::string CamelToUpper(const std::string &class_name);
std::string CamelToLower(const std::string &class_name);
// lowercased, underscored name to camel case
std::string ToCamel(const std::string &name);
// lowercase the string
std::string ToLower(const std::string &class_name);
std::string ToUpper(const std::string &class_name);
// full_name() to lowercase with underscores
std::string FullNameToLower(const std::string &full_name, const FileDescriptor *file);
std::string FullNameToUpper(const std::string &full_name, const FileDescriptor *file);
// full_name() to c-typename (with underscores for packages, otherwise camel case)
std::string FullNameToC(const std::string &class_name, const FileDescriptor *file);
// Splits, indents, formats, and prints comment lines
void PrintComment (io::Printer* printer, std::string comment);
// make a string of spaces as long as input
std::string ConvertToSpaces(const std::string &input);
// Strips ".proto" or ".protodevel" from the end of a filename.
std::string StripProto(const std::string& filename);
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
// Note: non-built-in type names will be qualified, meaning they will start
// with a ::. If you are using the type as a template parameter, you will
// need to insure there is a space between the < and the ::, because the
// ridiculous C++ standard defines "<:" to be a synonym for "[".
const char* PrimitiveTypeName(FieldDescriptor::CppType type);
// Get the declared type name in CamelCase format, as is used e.g. for the
// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
// Convert a file name into a valid identifier.
std::string FilenameIdentifier(const std::string& filename);
// Return the name of the BuildDescriptors() function for a given file.
std::string GlobalBuildDescriptorsName(const std::string& filename);
// return 'required', 'optional', or 'repeated'
std::string GetLabelName(FieldDescriptor::Label label);
// write IntRanges entries for a bunch of sorted values.
// returns the number of ranges there are to bsearch.
unsigned WriteIntRanges(io::Printer* printer, int n_values, const int *values, const std::string &name);
struct NameIndex
{
unsigned index;
const char *name;
};
int compare_name_indices_by_name(const void*, const void*);
// Return the syntax version of the file containing the field.
// This wrapper is needed to be able to compile against protobuf2.
inline int FieldSyntax(const FieldDescriptor* field) {
#ifdef HAVE_PROTO3
return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ? 3 : 2;
#else
return 2;
#endif
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_HELPERS_H__

View File

@@ -0,0 +1,633 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <algorithm>
#include <map>
#include <memory>
#include <protoc-c/c_message.h>
#include <protoc-c/c_enum.h>
#include <protoc-c/c_extension.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format.h>
#include <protobuf-c/protobuf-c.pb.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
// ===================================================================
MessageGenerator::MessageGenerator(const Descriptor* descriptor,
const std::string& dllexport_decl)
: descriptor_(descriptor),
dllexport_decl_(dllexport_decl),
field_generators_(descriptor),
nested_generators_(new std::unique_ptr<MessageGenerator>[
descriptor->nested_type_count()]),
enum_generators_(new std::unique_ptr<EnumGenerator>[
descriptor->enum_type_count()]),
extension_generators_(new std::unique_ptr<ExtensionGenerator>[
descriptor->extension_count()]) {
for (int i = 0; i < descriptor->nested_type_count(); i++) {
nested_generators_[i].reset(
new MessageGenerator(descriptor->nested_type(i), dllexport_decl));
}
for (int i = 0; i < descriptor->enum_type_count(); i++) {
enum_generators_[i].reset(
new EnumGenerator(descriptor->enum_type(i), dllexport_decl));
}
for (int i = 0; i < descriptor->extension_count(); i++) {
extension_generators_[i].reset(
new ExtensionGenerator(descriptor->extension(i), dllexport_decl));
}
}
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::
GenerateStructTypedef(io::Printer* printer) {
printer->Print("typedef struct $classname$ $classname$;\n",
"classname", FullNameToC(descriptor_->full_name(), descriptor_->file()));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateStructTypedef(printer);
}
}
void MessageGenerator::
GenerateEnumDefinitions(io::Printer* printer) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateEnumDefinitions(printer);
}
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDefinition(printer);
}
}
void MessageGenerator::
GenerateStructDefinition(io::Printer* printer) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateStructDefinition(printer);
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars["field_count"] = SimpleItoa(descriptor_->field_count());
if (dllexport_decl_.empty()) {
vars["dllexport"] = "";
} else {
vars["dllexport"] = dllexport_decl_ + " ";
}
// Generate the case enums for unions
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["opt_comma"] = ",";
vars["oneofname"] = CamelToUpper(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name(), oneof->file());
printer->Print("typedef enum {\n");
printer->Indent();
printer->Print(vars, "$ucclassname$__$oneofname$__NOT_SET = 0,\n");
for (int j = 0; j < oneof->field_count(); j++) {
const FieldDescriptor *field = oneof->field(j);
vars["fieldname"] = CamelToUpper(field->name());
vars["fieldnum"] = SimpleItoa(field->number());
bool isLast = j == oneof->field_count() - 1;
if (isLast) {
vars["opt_comma"] = "";
}
printer->Print(vars, "$ucclassname$__$oneofname$_$fieldname$ = $fieldnum$$opt_comma$\n");
}
printer->Print(vars, " PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE($ucclassname$__$oneofname$__CASE)\n");
printer->Outdent();
printer->Print(vars, "} $foneofname$Case;\n\n");
}
SourceLocation msgSourceLoc;
descriptor_->GetSourceLocation(&msgSourceLoc);
PrintComment (printer, msgSourceLoc.leading_comments);
const ProtobufCMessageOptions opt =
descriptor_->options().GetExtension(pb_c_msg);
vars["base"] = opt.base_field_name();
printer->Print(vars,
"struct $dllexport$ $classname$\n"
"{\n"
" ProtobufCMessage $base$;\n");
// Generate fields.
printer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
if (field->containing_oneof() == NULL) {
SourceLocation fieldSourceLoc;
field->GetSourceLocation(&fieldSourceLoc);
PrintComment (printer, fieldSourceLoc.leading_comments);
PrintComment (printer, fieldSourceLoc.trailing_comments);
field_generators_.get(field).GenerateStructMembers(printer);
}
}
// Generate unions from oneofs.
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["oneofname"] = CamelToLower(oneof->name());
vars["foneofname"] = FullNameToC(oneof->full_name(), oneof->file());
printer->Print(vars, "$foneofname$Case $oneofname$_case;\n");
printer->Print("union {\n");
printer->Indent();
for (int j = 0; j < oneof->field_count(); j++) {
const FieldDescriptor *field = oneof->field(j);
SourceLocation fieldSourceLoc;
field->GetSourceLocation(&fieldSourceLoc);
PrintComment (printer, fieldSourceLoc.leading_comments);
PrintComment (printer, fieldSourceLoc.trailing_comments);
field_generators_.get(field).GenerateStructMembers(printer);
}
printer->Outdent();
printer->Print(vars, "};\n");
}
printer->Outdent();
printer->Print(vars, "};\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
if (field->has_default_value()) {
field_generators_.get(field).GenerateDefaultValueDeclarations(printer);
}
}
printer->Print(vars, "#define $ucclassname$__INIT \\\n"
" { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor) \\\n ");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
if (field->containing_oneof() == NULL) {
printer->Print(", ");
field_generators_.get(field).GenerateStaticInit(printer);
}
}
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["foneofname"] = FullNameToUpper(oneof->full_name(), oneof->file());
// Initialize the case enum
printer->Print(vars, ", $foneofname$__NOT_SET");
// Initialize the union
printer->Print(", {0}");
}
printer->Print(" }\n\n\n");
}
void MessageGenerator::
GenerateHelperFunctionDeclarations(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init)
{
const ProtobufCMessageOptions opt =
descriptor_->options().GetExtension(pb_c_msg);
// Override parent settings, if needed
if (opt.has_gen_pack_helpers())
gen_pack = opt.gen_pack_helpers();
if (opt.has_gen_init_helpers())
gen_init = opt.gen_init_helpers();
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
bool nested_pack = !is_pack_deep ? opt.gen_pack_helpers() : gen_pack;
nested_generators_[i]->GenerateHelperFunctionDeclarations(printer, true,
nested_pack,
gen_init);
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
if (gen_init) {
printer->Print(vars,
"/* $classname$ methods */\n"
"void $lcclassname$__init\n"
" ($classname$ *message);\n"
);
}
if (gen_pack) {
printer->Print(vars,
"size_t $lcclassname$__get_packed_size\n"
" (const $classname$ *message);\n"
"size_t $lcclassname$__pack\n"
" (const $classname$ *message,\n"
" uint8_t *out);\n"
"size_t $lcclassname$__pack_to_buffer\n"
" (const $classname$ *message,\n"
" ProtobufCBuffer *buffer);\n"
"$classname$ *\n"
" $lcclassname$__unpack\n"
" (ProtobufCAllocator *allocator,\n"
" size_t len,\n"
" const uint8_t *data);\n"
"void $lcclassname$__free_unpacked\n"
" ($classname$ *message,\n"
" ProtobufCAllocator *allocator);\n"
);
}
}
void MessageGenerator::
GenerateDescriptorDeclarations(io::Printer* printer) {
printer->Print("extern const ProtobufCMessageDescriptor $name$__descriptor;\n",
"name", FullNameToLower(descriptor_->full_name(), descriptor_->file()));
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateDescriptorDeclarations(printer);
}
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDescriptorDeclarations(printer);
}
}
void MessageGenerator::GenerateClosureTypedef(io::Printer* printer)
{
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateClosureTypedef(printer);
}
std::map<std::string, std::string> vars;
vars["name"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
printer->Print(vars,
"typedef void (*$name$_Closure)\n"
" (const $name$ *message,\n"
" void *closure_data);\n");
}
static int
compare_pfields_by_number (const void *a, const void *b)
{
const FieldDescriptor *pa = *(const FieldDescriptor **)a;
const FieldDescriptor *pb = *(const FieldDescriptor **)b;
if (pa->number() < pb->number()) return -1;
if (pa->number() > pb->number()) return +1;
return 0;
}
void MessageGenerator::
GenerateHelperFunctionDefinitions(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init)
{
const ProtobufCMessageOptions opt =
descriptor_->options().GetExtension(pb_c_msg);
// Override parent settings, if needed
if (opt.has_gen_pack_helpers())
gen_pack = opt.gen_pack_helpers();
if (opt.has_gen_init_helpers())
gen_init = opt.gen_init_helpers();
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
bool nested_pack = !is_pack_deep ? opt.gen_pack_helpers() : gen_pack;
nested_generators_[i]->GenerateHelperFunctionDefinitions(printer, true,
nested_pack,
gen_init);
}
std::map<std::string, std::string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars["base"] = opt.base_field_name();
if (gen_init) {
printer->Print(vars,
"void $lcclassname$__init\n"
" ($classname$ *message)\n"
"{\n"
" static const $classname$ init_value = $ucclassname$__INIT;\n"
" *message = init_value;\n"
"}\n");
}
if (gen_pack) {
printer->Print(vars,
"size_t $lcclassname$__get_packed_size\n"
" (const $classname$ *message)\n"
"{\n"
" assert(message->$base$.descriptor == &$lcclassname$__descriptor);\n"
" return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));\n"
"}\n"
"size_t $lcclassname$__pack\n"
" (const $classname$ *message,\n"
" uint8_t *out)\n"
"{\n"
" assert(message->$base$.descriptor == &$lcclassname$__descriptor);\n"
" return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);\n"
"}\n"
"size_t $lcclassname$__pack_to_buffer\n"
" (const $classname$ *message,\n"
" ProtobufCBuffer *buffer)\n"
"{\n"
" assert(message->$base$.descriptor == &$lcclassname$__descriptor);\n"
" return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);\n"
"}\n"
"$classname$ *\n"
" $lcclassname$__unpack\n"
" (ProtobufCAllocator *allocator,\n"
" size_t len,\n"
" const uint8_t *data)\n"
"{\n"
" return ($classname$ *)\n"
" protobuf_c_message_unpack (&$lcclassname$__descriptor,\n"
" allocator, len, data);\n"
"}\n"
"void $lcclassname$__free_unpacked\n"
" ($classname$ *message,\n"
" ProtobufCAllocator *allocator)\n"
"{\n"
" if(!message)\n"
" return;\n"
" assert(message->$base$.descriptor == &$lcclassname$__descriptor);\n"
" protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);\n"
"}\n"
);
}
}
void MessageGenerator::
GenerateMessageDescriptor(io::Printer* printer, bool gen_init) {
std::map<std::string, std::string> vars;
vars["fullname"] = descriptor_->full_name();
vars["classname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars["shortname"] = ToCamel(descriptor_->name());
vars["n_fields"] = SimpleItoa(descriptor_->field_count());
vars["packagename"] = descriptor_->file()->package();
bool optimize_code_size = descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE;
const ProtobufCMessageOptions opt =
descriptor_->options().GetExtension(pb_c_msg);
// Override parent settings, if needed
if (opt.has_gen_init_helpers())
gen_init = opt.gen_init_helpers();
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
nested_generators_[i]->GenerateMessageDescriptor(printer, gen_init);
}
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
enum_generators_[i]->GenerateEnumDescriptor(printer);
}
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *fd = descriptor_->field(i);
if (fd->has_default_value()) {
field_generators_.get(fd).GenerateDefaultValueImplementations(printer);
}
}
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *fd = descriptor_->field(i);
const ProtobufCFieldOptions opt = fd->options().GetExtension(pb_c_field);
if (fd->has_default_value()) {
bool already_defined = false;
vars["name"] = fd->name();
vars["lcname"] = CamelToLower(fd->name());
vars["maybe_static"] = "static ";
vars["field_dv_ctype_suffix"] = "";
vars["default_value"] = field_generators_.get(fd).GetDefaultValue();
switch (fd->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
vars["field_dv_ctype"] = "int32_t";
break;
case FieldDescriptor::CPPTYPE_INT64:
vars["field_dv_ctype"] = "int64_t";
break;
case FieldDescriptor::CPPTYPE_UINT32:
vars["field_dv_ctype"] = "uint32_t";
break;
case FieldDescriptor::CPPTYPE_UINT64:
vars["field_dv_ctype"] = "uint64_t";
break;
case FieldDescriptor::CPPTYPE_FLOAT:
vars["field_dv_ctype"] = "float";
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
vars["field_dv_ctype"] = "double";
break;
case FieldDescriptor::CPPTYPE_BOOL:
vars["field_dv_ctype"] = "protobuf_c_boolean";
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
// NOTE: not supported by protobuf
vars["maybe_static"] = "";
vars["field_dv_ctype"] = "{ ... }";
GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
break;
case FieldDescriptor::CPPTYPE_STRING:
if (fd->type() == FieldDescriptor::TYPE_BYTES || opt.string_as_bytes())
{
vars["field_dv_ctype"] = "ProtobufCBinaryData";
}
else /* STRING type */
{
already_defined = true;
vars["maybe_static"] = "";
vars["field_dv_ctype"] = "char";
vars["field_dv_ctype_suffix"] = "[]";
}
break;
case FieldDescriptor::CPPTYPE_ENUM:
{
const EnumValueDescriptor *vd = fd->default_value_enum();
vars["field_dv_ctype"] = FullNameToC(vd->type()->full_name(), vd->type()->file());
break;
}
default:
GOOGLE_LOG(DFATAL) << "Unknown CPPTYPE";
break;
}
if (!already_defined)
printer->Print(vars, "$maybe_static$const $field_dv_ctype$ $lcclassname$__$lcname$__default_value$field_dv_ctype_suffix$ = $default_value$;\n");
}
}
if ( descriptor_->field_count() ) {
printer->Print(vars,
"static const ProtobufCFieldDescriptor $lcclassname$__field_descriptors[$n_fields$] =\n"
"{\n");
printer->Indent();
const FieldDescriptor **sorted_fields = new const FieldDescriptor *[descriptor_->field_count()];
for (int i = 0; i < descriptor_->field_count(); i++) {
sorted_fields[i] = descriptor_->field(i);
}
qsort (sorted_fields, descriptor_->field_count(),
sizeof (const FieldDescriptor *),
compare_pfields_by_number);
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = sorted_fields[i];
field_generators_.get(field).GenerateDescriptorInitializer(printer);
}
printer->Outdent();
printer->Print(vars, "};\n");
if (!optimize_code_size) {
NameIndex *field_indices = new NameIndex [descriptor_->field_count()];
for (int i = 0; i < descriptor_->field_count(); i++) {
field_indices[i].name = sorted_fields[i]->name().c_str();
field_indices[i].index = i;
}
qsort (field_indices, descriptor_->field_count(), sizeof (NameIndex),
compare_name_indices_by_name);
printer->Print(vars, "static const unsigned $lcclassname$__field_indices_by_name[] = {\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
vars["index"] = SimpleItoa(field_indices[i].index);
vars["name"] = field_indices[i].name;
printer->Print(vars, " $index$, /* field[$index$] = $name$ */\n");
}
printer->Print("};\n");
delete[] field_indices;
}
// create range initializers
int *values = new int[descriptor_->field_count()];
for (int i = 0; i < descriptor_->field_count(); i++) {
values[i] = sorted_fields[i]->number();
}
int n_ranges = WriteIntRanges(printer,
descriptor_->field_count(), values,
vars["lcclassname"] + "__number_ranges");
delete [] values;
delete [] sorted_fields;
vars["n_ranges"] = SimpleItoa(n_ranges);
} else {
/* MS compiler can't handle arrays with zero size and empty
* initialization list. Furthermore it is an extension of GCC only but
* not a standard. */
vars["n_ranges"] = "0";
printer->Print(vars,
"#define $lcclassname$__field_descriptors NULL\n"
"#define $lcclassname$__field_indices_by_name NULL\n"
"#define $lcclassname$__number_ranges NULL\n");
}
printer->Print(vars,
"const ProtobufCMessageDescriptor $lcclassname$__descriptor =\n"
"{\n"
" PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,\n");
if (optimize_code_size) {
printer->Print(" NULL,NULL,NULL,NULL, /* CODE_SIZE */\n");
} else {
printer->Print(vars,
" \"$fullname$\",\n"
" \"$shortname$\",\n"
" \"$classname$\",\n"
" \"$packagename$\",\n");
}
printer->Print(vars,
" sizeof($classname$),\n"
" $n_fields$,\n"
" $lcclassname$__field_descriptors,\n");
if (optimize_code_size) {
printer->Print(" NULL, /* CODE_SIZE */\n");
} else {
printer->Print(vars,
" $lcclassname$__field_indices_by_name,\n");
}
printer->Print(vars,
" $n_ranges$,"
" $lcclassname$__number_ranges,\n");
if (gen_init) {
printer->Print(vars,
" (ProtobufCMessageInit) $lcclassname$__init,\n");
} else {
printer->Print(vars,
" NULL, /* gen_init_helpers = false */\n");
}
printer->Print(vars,
" NULL,NULL,NULL /* reserved[123] */\n"
"};\n");
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,148 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__
#include <memory>
#include <string>
#include <google/protobuf/stubs/common.h>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
class EnumGenerator; // enum.h
class ExtensionGenerator; // extension.h
class MessageGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit MessageGenerator(const Descriptor* descriptor,
const std::string& dllexport_decl);
~MessageGenerator();
// Header stuff.
// Generate typedef.
void GenerateStructTypedef(io::Printer* printer);
// Generate descriptor prototype
void GenerateDescriptorDeclarations(io::Printer* printer);
// Generate descriptor prototype
void GenerateClosureTypedef(io::Printer* printer);
// Generate definitions of all nested enums (must come before class
// definitions because those classes use the enums definitions).
void GenerateEnumDefinitions(io::Printer* printer);
// Generate definitions for this class and all its nested types.
void GenerateStructDefinition(io::Printer* printer);
// Generate __INIT macro for populating this structure
void GenerateStructStaticInitMacro(io::Printer* printer);
// Generate standard helper functions declarations for this message.
void GenerateHelperFunctionDeclarations(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init);
// Source file stuff.
// Generate code that initializes the global variable storing the message's
// descriptor.
void GenerateMessageDescriptor(io::Printer* printer, bool gen_init);
void GenerateHelperFunctionDefinitions(io::Printer* printer,
bool is_pack_deep,
bool gen_pack,
bool gen_init);
private:
std::string GetDefaultValueC(const FieldDescriptor *fd);
const Descriptor* descriptor_;
std::string dllexport_decl_;
FieldGeneratorMap field_generators_;
std::unique_ptr<std::unique_ptr<MessageGenerator>[]> nested_generators_;
std::unique_ptr<std::unique_ptr<EnumGenerator>[]> enum_generators_;
std::unique_ptr<std::unique_ptr<ExtensionGenerator>[]> extension_generators_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_H__

View File

@@ -0,0 +1,129 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_message_field.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
using internal::WireFormat;
// ===================================================================
MessageFieldGenerator::
MessageFieldGenerator(const FieldDescriptor* descriptor)
: FieldGenerator(descriptor) {
}
MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["name"] = FieldName(descriptor_);
vars["type"] = FullNameToC(descriptor_->message_type()->full_name(), descriptor_->message_type()->file());
vars["deprecated"] = FieldDeprecated(descriptor_);
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(vars, "$type$ *$name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(vars, "size_t n_$name$$deprecated$;\n");
printer->Print(vars, "$type$ **$name$$deprecated$;\n");
break;
}
}
std::string MessageFieldGenerator::GetDefaultValue(void) const
{
/* XXX: update when protobuf gets support
* for default-values of message fields.
*/
return "NULL";
}
void MessageFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print("NULL");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print("0,NULL");
break;
}
}
void MessageFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
std::string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name(), descriptor_->message_type()->file()) + "__descriptor";
GenerateDescriptorInitializerGeneric(printer, false, "MESSAGE", addr);
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,97 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__
#include <map>
#include <string>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
class MessageFieldGenerator : public FieldGenerator {
public:
explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
~MessageFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
std::string GetDefaultValue(void) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_MESSAGE_FIELD_H__

View File

@@ -0,0 +1,211 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_primitive_field.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
PrimitiveFieldGenerator::
PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
: FieldGenerator(descriptor) {
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
std::string c_type;
std::map<std::string, std::string> vars;
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_SINT32 :
case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_INT32 : c_type = "int32_t"; break;
case FieldDescriptor::TYPE_SINT64 :
case FieldDescriptor::TYPE_SFIXED64:
case FieldDescriptor::TYPE_INT64 : c_type = "int64_t"; break;
case FieldDescriptor::TYPE_UINT32 :
case FieldDescriptor::TYPE_FIXED32 : c_type = "uint32_t"; break;
case FieldDescriptor::TYPE_UINT64 :
case FieldDescriptor::TYPE_FIXED64 : c_type = "uint64_t"; break;
case FieldDescriptor::TYPE_FLOAT : c_type = "float"; break;
case FieldDescriptor::TYPE_DOUBLE : c_type = "double"; break;
case FieldDescriptor::TYPE_BOOL : c_type = "protobuf_c_boolean"; break;
case FieldDescriptor::TYPE_ENUM :
case FieldDescriptor::TYPE_STRING :
case FieldDescriptor::TYPE_BYTES :
case FieldDescriptor::TYPE_GROUP :
case FieldDescriptor::TYPE_MESSAGE : GOOGLE_LOG(FATAL) << "not a primitive type"; break;
// No default because we want the compiler to complain if any new
// types are added.
}
vars["c_type"] = c_type;
vars["name"] = FieldName(descriptor_);
vars["deprecated"] = FieldDeprecated(descriptor_);
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(vars, "$c_type$ $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (descriptor_->containing_oneof() == NULL && FieldSyntax(descriptor_) == 2)
printer->Print(vars, "protobuf_c_boolean has_$name$$deprecated$;\n");
printer->Print(vars, "$c_type$ $name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(vars, "size_t n_$name$$deprecated$;\n");
printer->Print(vars, "$c_type$ *$name$$deprecated$;\n");
break;
}
}
std::string PrimitiveFieldGenerator::GetDefaultValue() const
{
/* XXX: SimpleItoa seems woefully inadequate for anything but int32,
* but that's what protobuf uses. */
switch (descriptor_->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
return SimpleItoa(descriptor_->default_value_int32());
case FieldDescriptor::CPPTYPE_INT64:
return SimpleItoa(descriptor_->default_value_int64()) + "ll";
case FieldDescriptor::CPPTYPE_UINT32:
return SimpleItoa(descriptor_->default_value_uint32()) + "u";
case FieldDescriptor::CPPTYPE_UINT64:
return SimpleItoa(descriptor_->default_value_uint64()) + "ull";
case FieldDescriptor::CPPTYPE_FLOAT:
return SimpleFtoa(descriptor_->default_value_float());
case FieldDescriptor::CPPTYPE_DOUBLE:
return SimpleDtoa(descriptor_->default_value_double());
case FieldDescriptor::CPPTYPE_BOOL:
return descriptor_->default_value_bool() ? "1" : "0";
default:
GOOGLE_LOG(DFATAL) << "unexpected CPPTYPE in c_primitive_field";
return "UNEXPECTED_CPPTYPE";
}
}
void PrimitiveFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
if (descriptor_->has_default_value()) {
vars["default_value"] = GetDefaultValue();
} else {
vars["default_value"] = "0";
}
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
printer->Print(vars, "$default_value$");
break;
case FieldDescriptor::LABEL_OPTIONAL:
if (FieldSyntax(descriptor_) == 2)
printer->Print(vars, "0, ");
printer->Print(vars, "$default_value$");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print("0,NULL");
break;
}
}
void PrimitiveFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
std::string c_type_macro;
switch (descriptor_->type()) {
#define WRITE_CASE(shortname) case FieldDescriptor::TYPE_##shortname: c_type_macro = #shortname; break;
WRITE_CASE(INT32)
WRITE_CASE(SINT32)
WRITE_CASE(UINT32)
WRITE_CASE(SFIXED32)
WRITE_CASE(FIXED32)
WRITE_CASE(INT64)
WRITE_CASE(SINT64)
WRITE_CASE(UINT64)
WRITE_CASE(FIXED64)
WRITE_CASE(SFIXED64)
WRITE_CASE(FLOAT)
WRITE_CASE(DOUBLE)
WRITE_CASE(BOOL)
#undef WRITE_CASE
case FieldDescriptor::TYPE_ENUM :
case FieldDescriptor::TYPE_STRING :
case FieldDescriptor::TYPE_BYTES :
case FieldDescriptor::TYPE_GROUP :
case FieldDescriptor::TYPE_MESSAGE : GOOGLE_LOG(FATAL) << "not a primitive type"; break;
// No default because we want the compiler to complain if any new
// types are added.
}
GenerateDescriptorInitializerGeneric(printer, true, c_type_macro, "NULL");
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,96 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__
#include <map>
#include <string>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
class PrimitiveFieldGenerator : public FieldGenerator {
public:
explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
~PrimitiveFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
std::string GetDefaultValue(void) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_PRIMITIVE_FIELD_H__

View File

@@ -0,0 +1,294 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_service.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
const std::string& dllexport_decl)
: descriptor_(descriptor) {
vars_["name"] = descriptor_->name();
vars_["fullname"] = descriptor_->full_name();
vars_["cname"] = FullNameToC(descriptor_->full_name(), descriptor_->file());
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["ucfullname"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file());
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
vars_["package"] = descriptor_->file()->package();
if (dllexport_decl.empty()) {
vars_["dllexport"] = "";
} else {
vars_["dllexport"] = dllexport_decl + " ";
}
}
ServiceGenerator::~ServiceGenerator() {}
// Header stuff.
void ServiceGenerator::GenerateMainHFile(io::Printer* printer)
{
GenerateVfuncs(printer);
GenerateInitMacros(printer);
GenerateCallersDeclarations(printer);
}
void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
{
printer->Print(vars_,
"typedef struct $cname$_Service $cname$_Service;\n"
"struct $cname$_Service\n"
"{\n"
" ProtobufCService base;\n");
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
printer->Print(vars_,
" void (*$method$)($cname$_Service *service,\n"
" $metpad$ const $input_typename$ *input,\n"
" $metpad$ $output_typename$_Closure closure,\n"
" $metpad$ void *closure_data);\n");
}
printer->Print(vars_,
"};\n");
printer->Print(vars_,
"typedef void (*$cname$_ServiceDestroy)($cname$_Service *);\n"
"void $lcfullname$__init ($cname$_Service *service,\n"
" $lcfullpadd$ $cname$_ServiceDestroy destroy);\n");
}
void ServiceGenerator::GenerateInitMacros(io::Printer* printer)
{
printer->Print(vars_,
"#define $ucfullname$__BASE_INIT \\\n"
" { &$lcfullname$__descriptor, protobuf_c_service_invoke_internal, NULL }\n"
"#define $ucfullname$__INIT(function_prefix__) \\\n"
" { $ucfullname$__BASE_INIT");
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
printer->Print(vars_,
",\\\n function_prefix__ ## $method$");
}
printer->Print(vars_,
" }\n");
}
void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
{
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
printer->Print(vars_,
"void $lcfullname$__$method$(ProtobufCService *service,\n"
" $padddddddddddddddddd$ const $input_typename$ *input,\n"
" $padddddddddddddddddd$ $output_typename$_Closure closure,\n"
" $padddddddddddddddddd$ void *closure_data);\n");
}
}
void ServiceGenerator::GenerateDescriptorDeclarations(io::Printer* printer)
{
printer->Print(vars_, "extern const ProtobufCServiceDescriptor $lcfullname$__descriptor;\n");
}
// Source file stuff.
void ServiceGenerator::GenerateCFile(io::Printer* printer)
{
GenerateServiceDescriptor(printer);
GenerateCallersImplementations(printer);
GenerateInit(printer);
}
void ServiceGenerator::GenerateInit(io::Printer* printer)
{
printer->Print(vars_,
"void $lcfullname$__init ($cname$_Service *service,\n"
" $lcfullpadd$ $cname$_ServiceDestroy destroy)\n"
"{\n"
" protobuf_c_service_generated_init (&service->base,\n"
" &$lcfullname$__descriptor,\n"
" (ProtobufCServiceDestroy) destroy);\n"
"}\n");
}
struct MethodIndexAndName { unsigned i; const char *name; };
static int
compare_method_index_and_name_by_name (const void *a, const void *b)
{
const MethodIndexAndName *ma = (const MethodIndexAndName *) a;
const MethodIndexAndName *mb = (const MethodIndexAndName *) b;
return strcmp (ma->name, mb->name);
}
void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
{
int n_methods = descriptor_->method_count();
MethodIndexAndName *mi_array = new MethodIndexAndName[n_methods];
bool optimize_code_size = descriptor_->file()->options().has_optimize_for() &&
descriptor_->file()->options().optimize_for() ==
FileOptions_OptimizeMode_CODE_SIZE;
vars_["n_methods"] = SimpleItoa(n_methods);
printer->Print(vars_, "static const ProtobufCMethodDescriptor $lcfullname$__method_descriptors[$n_methods$] =\n"
"{\n");
for (int i = 0; i < n_methods; i++) {
const MethodDescriptor *method = descriptor_->method(i);
vars_["method"] = method->name();
vars_["input_descriptor"] = "&" + FullNameToLower(method->input_type()->full_name(), method->input_type()->file()) + "__descriptor";
vars_["output_descriptor"] = "&" + FullNameToLower(method->output_type()->full_name(), method->output_type()->file()) + "__descriptor";
if (optimize_code_size) {
printer->Print(vars_,
" { NULL, $input_descriptor$, $output_descriptor$ }, /* CODE_SIZE */\n");
} else {
printer->Print(vars_,
" { \"$method$\", $input_descriptor$, $output_descriptor$ },\n");
}
mi_array[i].i = i;
mi_array[i].name = method->name().c_str();
}
printer->Print(vars_, "};\n");
if (!optimize_code_size) {
qsort ((void*)mi_array, n_methods, sizeof (MethodIndexAndName),
compare_method_index_and_name_by_name);
printer->Print(vars_, "const unsigned $lcfullname$__method_indices_by_name[] = {\n");
for (int i = 0; i < n_methods; i++) {
vars_["i"] = SimpleItoa(mi_array[i].i);
vars_["name"] = mi_array[i].name;
vars_["comma"] = (i + 1 < n_methods) ? "," : " ";
printer->Print(vars_, " $i$$comma$ /* $name$ */\n");
}
printer->Print(vars_, "};\n");
vars_["name"] = descriptor_->name();
}
if (optimize_code_size) {
printer->Print(vars_, "const ProtobufCServiceDescriptor $lcfullname$__descriptor =\n"
"{\n"
" PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC,\n"
" NULL,NULL,NULL,NULL, /* CODE_SIZE */\n"
" $n_methods$,\n"
" $lcfullname$__method_descriptors,\n"
" NULL /* CODE_SIZE */\n"
"};\n");
} else {
printer->Print(vars_, "const ProtobufCServiceDescriptor $lcfullname$__descriptor =\n"
"{\n"
" PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC,\n"
" \"$fullname$\",\n"
" \"$name$\",\n"
" \"$cname$\",\n"
" \"$package$\",\n"
" $n_methods$,\n"
" $lcfullname$__method_descriptors,\n"
" $lcfullname$__method_indices_by_name\n"
"};\n");
}
delete[] mi_array;
}
void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer)
{
for (int i = 0; i < descriptor_->method_count(); i++) {
const MethodDescriptor *method = descriptor_->method(i);
std::string lcname = CamelToLower(method->name());
std::string lcfullname = FullNameToLower(descriptor_->full_name(), descriptor_->file());
vars_["method"] = lcname;
vars_["metpad"] = ConvertToSpaces(lcname);
vars_["input_typename"] = FullNameToC(method->input_type()->full_name(), method->input_type()->file());
vars_["output_typename"] = FullNameToC(method->output_type()->full_name(), method->output_type()->file());
vars_["padddddddddddddddddd"] = ConvertToSpaces(lcfullname + "__" + lcname);
vars_["index"] = SimpleItoa(i);
printer->Print(vars_,
"void $lcfullname$__$method$(ProtobufCService *service,\n"
" $padddddddddddddddddd$ const $input_typename$ *input,\n"
" $padddddddddddddddddd$ $output_typename$_Closure closure,\n"
" $padddddddddddddddddd$ void *closure_data)\n"
"{\n"
" assert(service->descriptor == &$lcfullname$__descriptor);\n"
" service->invoke(service, $index$, (const ProtobufCMessage *) input, (ProtobufCClosure) closure, closure_data);\n"
"}\n");
}
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,112 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__
#define GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__
#include <map>
#include <string>
#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
namespace io {
class Printer; // printer.h
}
}
namespace protobuf {
namespace compiler {
namespace c {
class ServiceGenerator {
public:
// See generator.cc for the meaning of dllexport_decl.
explicit ServiceGenerator(const ServiceDescriptor* descriptor,
const std::string& dllexport_decl);
~ServiceGenerator();
// Header stuff.
void GenerateMainHFile(io::Printer* printer);
void GenerateVfuncs(io::Printer* printer);
void GenerateInitMacros(io::Printer* printer);
void GenerateDescriptorDeclarations(io::Printer* printer);
void GenerateCallersDeclarations(io::Printer* printer);
// Source file stuff.
void GenerateCFile(io::Printer* printer);
void GenerateServiceDescriptor(io::Printer* printer);
void GenerateInit(io::Printer* printer);
void GenerateCallersImplementations(io::Printer* printer);
const ServiceDescriptor* descriptor_;
std::map<std::string, std::string> vars_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_SERVICE_H__

View File

@@ -0,0 +1,160 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#include <protoc-c/c_string_field.h>
#include <protoc-c/c_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <protobuf-c/protobuf-c.pb.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
using internal::WireFormat;
void SetStringVariables(const FieldDescriptor* descriptor,
std::map<std::string, std::string>* variables) {
(*variables)["name"] = FieldName(descriptor);
(*variables)["default"] = FullNameToLower(descriptor->full_name(), descriptor->file())
+ "__default_value";
(*variables)["deprecated"] = FieldDeprecated(descriptor);
}
// ===================================================================
StringFieldGenerator::
StringFieldGenerator(const FieldDescriptor* descriptor)
: FieldGenerator(descriptor) {
SetStringVariables(descriptor, &variables_);
}
StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char *$name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char **$name$$deprecated$;\n");
break;
}
}
void StringFieldGenerator::GenerateDefaultValueDeclarations(io::Printer* printer) const
{
printer->Print(variables_, "extern char $default$[];\n");
}
void StringFieldGenerator::GenerateDefaultValueImplementations(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
vars["default"] = variables_.find("default")->second;
vars["escaped"] = CEscape(descriptor_->default_value_string());
printer->Print(vars, "char $default$[] = \"$escaped$\";\n");
}
std::string StringFieldGenerator::GetDefaultValue(void) const
{
return variables_.find("default")->second;
}
void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
if (descriptor_->has_default_value()) {
vars["default"] = GetDefaultValue();
} else if (FieldSyntax(descriptor_) == 2) {
vars["default"] = "NULL";
} else if (opt.const_strings()) {
vars["default"] = "(const char *)protobuf_c_empty_string";
} else {
vars["default"] = "(char *)protobuf_c_empty_string";
}
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(vars, "$default$");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(vars, "0,NULL");
break;
}
}
void StringFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
GenerateDescriptorInitializerGeneric(printer, false, "STRING", "NULL");
}
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google

View File

@@ -0,0 +1,100 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
// Copyright (c) 2008-2013, Dave Benson. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Modified to implement C code by Dave Benson.
#ifndef GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__
#include <map>
#include <string>
#include <protoc-c/c_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace c {
class StringFieldGenerator : public FieldGenerator {
public:
explicit StringFieldGenerator(const FieldDescriptor* descriptor);
~StringFieldGenerator();
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateDefaultValueDeclarations(io::Printer* printer) const;
void GenerateDefaultValueImplementations(io::Printer* printer) const;
std::string GetDefaultValue(void) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
std::map<std::string, std::string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
};
} // namespace c
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_C_STRING_FIELD_H__

View File

@@ -0,0 +1,22 @@
#include <string>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <protoc-c/c_generator.h>
int main(int argc, char* argv[]) {
google::protobuf::compiler::c::CGenerator c_generator;
std::string invocation_name = argv[0];
std::string invocation_basename = invocation_name.substr(invocation_name.find_last_of("/") + 1);
const std::string legacy_name = "protoc-c";
if (invocation_basename == legacy_name) {
google::protobuf::compiler::CommandLineInterface cli;
cli.RegisterGenerator("--c_out", &c_generator, "Generate C/H files.");
cli.SetVersionInfo(PACKAGE_STRING);
return cli.Run(argc, argv);
}
return google::protobuf::compiler::PluginMain(argc, argv, &c_generator);
}

View File

@@ -0,0 +1,38 @@
There are two tests.
"test-generated-code" is a simple test that can easily be adapted.
"test-generated-code2" is a comprehensive test.
--
If you have a quick problem, hack at "test-generated-code";
but i don't want that file to be too hard to navigate,
so you must eventually add a test to "test-generated-code2".
I appreciate additional test cases!
Please submit them as issues in the tracking system, or email me.
--
Here are the files involved in each test:
test.proto Protobuf declarations for the simple test.
test.pb-c.c Protobuf-C generated code based on test.proto
test.pb-c.h Protobuf-C generated code based on test.proto
test-full.proto Protobuf declarations for the exhaustive test.
test-full.pb-c.c Protobuf-C generated code based on test-full.proto
test-full.pb-c.h Protobuf-C generated code based on test-full.proto
test-full.pb.cc Protobuf (C++) generated code based on test-full.proto
test-full.pb.h Protobuf (C++) generated code based on test-full.proto
generated-code/
test-generated-code.c Actual test code.
test-generated-code Test executable.
generated-code2/
cxx-generate-packed-data.cc C++ code to generated data to compare with C.
cxx-generate-packed-data Program whichs generates data (using C++ api)
test-full-cxx-output.inc Output of cxx-generate-packed-data.
test-generated-code2.c Actual test code.
test-generated-code2 Test executable.

View File

@@ -0,0 +1,71 @@
#ifdef PROTO3
#include "t/test-proto3.pb-c.h"
#else
#include "t/test.pb-c.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
Foo__Person__PhoneNumber__Comment comment = FOO__PERSON__PHONE_NUMBER__COMMENT__INIT;
Foo__Person__PhoneNumber phone = FOO__PERSON__PHONE_NUMBER__INIT;
Foo__Person__PhoneNumber *phone_numbers[1];
Foo__Person person = FOO__PERSON__INIT;
Foo__Person *person2;
unsigned char simple_pad[8];
size_t size, size2;
unsigned char *packed;
ProtobufCBufferSimple bs = PROTOBUF_C_BUFFER_SIMPLE_INIT (simple_pad);
comment.comment = "protobuf-c guy";
phone.number = "1234";
#ifndef PROTO3
phone.has_type = 1;
#endif
phone.type = FOO__PERSON__PHONE_TYPE__WORK;
phone.comment = &comment;
phone_numbers[0] = &phone;
person.name = "dave b";
person.id = 42;
person.n_phone = 1;
person.phone = phone_numbers;
size = foo__person__get_packed_size (&person);
packed = malloc (size);
assert (packed);
size2 = foo__person__pack (&person, packed);
assert (size == size2);
foo__person__pack_to_buffer (&person, &bs.base);
assert (bs.len == size);
assert (memcmp (bs.data, packed, size) == 0);
PROTOBUF_C_BUFFER_SIMPLE_CLEAR (&bs);
person2 = foo__person__unpack (NULL, size, packed);
assert (person2 != NULL);
assert (person2->id == 42);
#ifndef PROTO3
assert (person2->email == NULL);
#else
assert (strcmp (person2->email, "") == 0);
#endif
assert (strcmp (person2->name, "dave b") == 0);
assert (person2->n_phone == 1);
assert (strcmp (person2->phone[0]->number, "1234") == 0);
assert (person2->phone[0]->type == FOO__PERSON__PHONE_TYPE__WORK);
assert (strcmp (person2->phone[0]->comment->comment, "protobuf-c guy") == 0);
foo__person__free_unpacked (person2, NULL);
free (packed);
printf ("test succeeded.\n");
return 0;
}

View File

@@ -0,0 +1,62 @@
/* data included from the c++ packed-data generator,
and from the c test code. */
#define THOUSAND 1000
#define MILLION 1000000
#define BILLION 1000000000LL
#define TRILLION 1000000000000LL
#define QUADRILLION 1000000000000000LL
#define QUINTILLION 1000000000000000000LL
int32_t int32_arr0[2] = { -1, 1 };
int32_t int32_arr1[5] = { 42, 666, -1123123, 0, 47 };
int32_t int32_arr_min_max[2] = { INT32_MIN, INT32_MAX };
uint32_t uint32_roundnumbers[4] = { BILLION, MILLION, 1, 0 };
uint32_t uint32_0_max[2] = { 0, UINT32_MAX };
int64_t int64_roundnumbers[15] = { -QUINTILLION, -QUADRILLION, -TRILLION,
-BILLION, -MILLION, -THOUSAND,
1,
THOUSAND, MILLION, BILLION,
TRILLION, QUADRILLION, QUINTILLION };
int64_t int64_min_max[2] = { INT64_MIN, INT64_MAX };
uint64_t uint64_roundnumbers[9] = { 1,
THOUSAND, MILLION, BILLION,
TRILLION, QUADRILLION, QUINTILLION };
uint64_t uint64_0_1_max[3] = { 0, 1, UINT64_MAX };
uint64_t uint64_random[] = {0,
666,
4200000000ULL,
16ULL * (uint64_t) QUINTILLION + 33 };
#define FLOATING_POINT_RANDOM \
-1000.0, -100.0, -42.0, 0, 666, 131313
float float_random[] = { FLOATING_POINT_RANDOM };
double double_random[] = { FLOATING_POINT_RANDOM };
protobuf_c_boolean boolean_0[] = {0 };
protobuf_c_boolean boolean_1[] = {1 };
protobuf_c_boolean boolean_random[] = {0,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,0 };
TEST_ENUM_SMALL_TYPE_NAME enum_small_0[] = { TEST_ENUM_SMALL(VALUE) };
TEST_ENUM_SMALL_TYPE_NAME enum_small_1[] = { TEST_ENUM_SMALL(OTHER_VALUE) };
#define T(v) (TEST_ENUM_SMALL_TYPE_NAME)(v)
TEST_ENUM_SMALL_TYPE_NAME enum_small_random[] = {T(0),T(1),T(1),T(0),T(0),T(1),T(1),T(1),T(0),T(0),T(0),T(0),T(0),T(1),T(1),T(1),T(1),T(1),T(1),T(0),T(1),T(1),T(0),T(1),T(1),T(0) };
#undef T
#define T(v) (TEST_ENUM_TYPE_NAME)(v)
TEST_ENUM_TYPE_NAME enum_0[] = { T(0) };
TEST_ENUM_TYPE_NAME enum_1[] = { T(1) };
TEST_ENUM_TYPE_NAME enum_random[] = {
T(0), T(268435455), T(127), T(16384), T(16383),
T(2097152), T(2097151), T(128), T(268435456),
T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) };
#undef T
const char *repeated_strings_0[] = { "onestring" };
const char *repeated_strings_1[] = { "two", "string" };
const char *repeated_strings_2[] = { "many", "tiny", "little", "strings", "should", "be", "handled" };
const char *repeated_strings_3[] = { "one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };

View File

@@ -0,0 +1 @@
issue204

View File

@@ -0,0 +1,48 @@
#include <stdlib.h>
#include "t/issue251/issue251.pb-c.h"
int main(void)
{
TwoOneofs msg = TWO_ONEOFS__INIT;
const ProtobufCFieldDescriptor *field;
unsigned off1, off2, off_name;
field = protobuf_c_message_descriptor_get_field_by_name(
msg.base.descriptor,
"first_oneof");
assert (field);
off_name = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
10);
assert (field);
off1 = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
11);
assert (field);
off2 = field->offset;
assert (off_name == off1);
assert (off1 == off2);
field = protobuf_c_message_descriptor_get_field_by_name(
msg.base.descriptor,
"second_oneof");
assert (field);
off_name = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
20);
assert (field);
off1 = field->offset;
field = protobuf_c_message_descriptor_get_field(
msg.base.descriptor,
21);
assert (field);
off2 = field->offset;
assert (off_name == off1);
assert (off1 == off2);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,15 @@
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).use_oneof_field_name = true;
message two_oneofs {
oneof first_oneof {
bool a = 10;
bool b = 11;
}
oneof second_oneof {
bool c = 20;
bool d = 21;
}
}

View File

@@ -0,0 +1 @@
issue220

View File

@@ -0,0 +1,13 @@
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
#include "t/issue220/issue220.pb-c.h"
int main(void)
{
assert(_MESSAGE_TYPE1__FLAG_IS_INT_SIZE == INT_MAX);
assert(_MESSAGE_TYPE2__ANOTHER_FLAG_IS_INT_SIZE == INT_MAX);
assert(_TOP_LEVEL__SUBMESSAGES__CASE_IS_INT_SIZE == INT_MAX);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,20 @@
message TopLevel {
oneof submessages {
MessageType1 type1 = 1;
MessageType2 type2 = 2;
}
}
message MessageType1 {
enum Flag {
OK = 1;
}
optional Flag flag = 1;
}
message MessageType2 {
enum AnotherFlag {
OK = 1;
}
optional AnotherFlag flag = 1;
}

View File

@@ -0,0 +1 @@
issue251

View File

@@ -0,0 +1,12 @@
#include <stdlib.h>
#include "t/issue251/issue251.pb-c.h"
int main(void)
{
/*
* The problem in #251 caused invalid code to be generated in the
* .pb-c.h file, so there's nothing for us to do here.
*/
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,11 @@
message two_oneofs {
oneof first_oneof {
bool a = 10;
bool b = 11;
}
oneof second_oneof {
bool c = 20;
bool d = 21;
}
}

View File

@@ -0,0 +1 @@
issue330

View File

@@ -0,0 +1,25 @@
#include <stdlib.h>
#include <string.h>
#include "t/issue330/issue330.pb-c.h"
int main(void)
{
/* Output of $ echo acl_id: 2 acl_id: 3 | protoc issue330.proto \
* --encode=pbr_route | xxd -i: 0x52, 0x02, 0x02, 0x03
*/
uint8_t protoc[] = {0x52, 0x02, 0x02, 0x03};
PbrRoute msg = PBR_ROUTE__INIT;
int ids[] = {2, 3};
uint8_t buf[16] = {0};
size_t sz = 0;
msg.n_acl_id = 2;
msg.acl_id = ids;
sz = pbr_route__pack(&msg, buf);
assert (sz == sizeof protoc);
assert (memcmp (protoc, buf, sz) == 0);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,5 @@
syntax = "proto3";
message pbr_route {
repeated int32 acl_id = 10;
}

View File

@@ -0,0 +1 @@
issue375

View File

@@ -0,0 +1,24 @@
#include <assert.h>
#include <stdlib.h>
#include "t/issue375/issue375.pb-c.h"
int main(void) {
// This buffer represents some serialized bytes where we have a length
// delimiter of 2^32 - 1 bytes for a particular repeated int32 field.
// We want to make sure that parsing a length delimiter this large does
// not cause a problematic integer overflow.
uint8_t buffer[] = {
// Field 1 with wire type 2 (length-delimited)
0x0a,
// Varint length delimiter: 2^32 - 1
0xff, 0xff, 0xff, 0xff, 0x0f,
};
// The parser should detect that this message is malformed and return
// null.
Issue375__TestMessage* m =
issue375__test_message__unpack(NULL, sizeof(buffer), buffer);
assert(m == NULL);
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,7 @@
syntax = "proto2";
package issue375;
message TestMessage {
repeated int32 nums = 1;
}

View File

@@ -0,0 +1,12 @@
syntax = "proto3";
message EnumIntTest {
enum Label {
LABEL_1 = 0;
LABEL_2 = 1;
}
oneof label {
Label label_label = 123;
uint64 label_uint64 = 124;
}
}

View File

@@ -0,0 +1 @@
issue440

View File

@@ -0,0 +1,30 @@
#include <stdlib.h>
#include <string.h>
#include "t/issue440/issue440.pb-c.h"
int main(void)
{
/* Output of $ echo "int: 1 int: -142342 int: 0 int: 423423222" | \
* protoc issue440.proto --encode=Int | xxd -i:
* 0x0a, 0x11, 0x01, 0xfa, 0xa7, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
* 0x01, 0x00, 0xf6, 0xd9, 0xf3, 0xc9, 0x01
*
* Output of $ echo "int: 1 int: -142342 int: 0 int: 423423222" | \
* protoc issue440.proto --encode=Int | protoc issue440.proto \
* --decode=Boolean: boolean: true boolean: true boolean: false boolean: true
*/
uint8_t protoc[] = {0x0a, 0x11, 0x01, 0xfa, 0xa7, 0xf7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf6, 0xd9, 0xf3, 0xc9,
0x01};
Boolean *msg = boolean__unpack (NULL, sizeof protoc, protoc);
assert(msg);
assert(msg->n_boolean == 4);
assert(msg->boolean[0] == 1);
assert(msg->boolean[1] == 1);
assert(msg->boolean[2] == 0);
assert(msg->boolean[3] == 1);
boolean__free_unpacked (msg, NULL);
return EXIT_SUCCESS;
}

Some files were not shown because too many files have changed in this diff Show More