initial commit via gitinitshit
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
build
|
||||||
|
old
|
||||||
|
*.old*
|
||||||
|
*.tmp*
|
||||||
|
*.bak*
|
||||||
|
sdkconfig
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Links and Resources
|
||||||
|
## General
|
||||||
|
* [ESP-IDF Github (v5.5)](https://github.com/espressif/esp-idf/tree/release/v5.5)
|
||||||
|
* [ESP-IDF Examples (v5.5)](https://github.com/espressif/esp-idf/tree/release/v5.5/examples)
|
||||||
|
* [esp-idf-tools (master)](https://github.com/PrincessPi3/esp-idf-tools)
|
||||||
|
|
||||||
|
## Devkit WT99P4C5-S1
|
||||||
|
* [Product Page](https://en.wireless-tag.com/product-item-66.html)
|
||||||
|
* [Sale Page (Aliexpress)](https://www.aliexpress.us/item/3256809513099697.html)
|
||||||
|
* [Guide](assets/devkit/WT99P4C5-S1_Guide_en_v1.2.pdf)
|
||||||
|
* [Schematic](assets/devkit/WT99P4C5-S1_Guide_en_v1.2.pdf)
|
||||||
|
* [Github Examples](https://github.com/wireless-tag-com/DevBoard/tree/WT99P4C5-S1)
|
||||||
|
|
||||||
|
## ESP32-C5
|
||||||
|
* [Product Page](https://www.espressif.com/en/products/socs/esp32-c5)
|
||||||
|
* [ESP-IDF Docs (C5)](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32c5/index.html)
|
||||||
|
* esp-hosted docs
|
||||||
|
* esp-hosted slave docs
|
||||||
|
* esp-idf example slave
|
||||||
|
* [ESP32-C5 Datasheet (Pre-Release v0.6)](assets/esp32c5/esp32-c5-wroom-1_wroom-1u_datasheet_en.pdf)
|
||||||
|
* [ESP32-C5 Technical Reference (Pre-Release v0.2)](assets/esp32c5/esp32-c5_technical_reference_manual_en.pdf)
|
||||||
|
|
||||||
|
## ESP32-P4
|
||||||
|
* [Product Page](https://www.espressif.com/en/products/socs/esp32-p4)
|
||||||
|
* [ESP-IDF Docs (P4)](https://docs.espressif.com/projects/esp-idf/en/v5.5/esp32p4/index.html)
|
||||||
|
* [Remote Control Transceiver Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/peripherals/rmt.html)
|
||||||
|
* [ESP-IDF Examples RMT](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/peripherals/rmt)
|
||||||
|
* [Dedicated GPIO Docs](https://docs.espressif.com/projects/esp-idf/en/v5.5/esp32p4/api-reference/peripherals/dedic_gpio.html)
|
||||||
|
[ESP-IDF Examples Dedicated GPIO](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/peripherals/dedicated_gpio)
|
||||||
|
* [ADC Continuous Mode Docs](https://docs.espressif.com/projects/esp-idf/en/v5.5/esp32p4/api-reference/peripherals/adc_continuous.html)
|
||||||
|
* [ESP-IDF Example ADC DMA](https://github.com/espressif/esp-idf/tree/v5.5/examples/peripherals/adc/continuous_read)
|
||||||
|
* [Console Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/console.html)
|
||||||
|
* [ESP-IDF Examples Console](https://github.com/espressif/esp-idf/tree/02c5f2db/examples/system/console/)
|
||||||
|
* [FreeRTOS IDF Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/freertos_idf.html)
|
||||||
|
* [ESP-IDF Examples FreeRTOS](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/system/freertos)
|
||||||
|
* [Inter-Processor Call (IPC) Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/ipc.html)
|
||||||
|
* [ESP-IDF Examples IPC RISCV](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/system/ipc/ipc_isr/riscv)
|
||||||
|
* [Low Power Core (LP) Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-reference/system/ulp-lp-core.html)
|
||||||
|
* [ESP-IDf Examples LP](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/system/ulp/lp_core)
|
||||||
|
* [PSRAM/SPI RAM/External RAM Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-guides/external-ram.html)
|
||||||
|
* [Execute In Place (XIP) Docs](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32p4/api-guides/external-ram.html#external-ram-config-xip)
|
||||||
|
* [ESP-IDF Example XIP](https://github.com/espressif/esp-idf/tree/release/v5.5/examples/system/xip_from_psram)
|
||||||
|
* [ESP-Hosted-NG Docs](https://github.com/espressif/esp-hosted/blob/release/fg-v1.0.0.0.0/esp_hosted_ng/README.md)
|
||||||
|
* [ESP-Hosted-NG Github (release fg-v1.0.0.0.0)](https://github.com/espressif/esp-hosted/tree/release/fg-v1.0.0.0.0)
|
||||||
|
* ESP-Hosted-NG Host device
|
||||||
|
* [ESP32-P4 Datasheet (Pre-Release v0.5)](assets/esp32p4/esp32-p4_datasheet_en.pdf)
|
||||||
|
* [ESP32-P4 Technical Reference (Pre-Release v0.1)](assets/esp32p4/esp32-p4_technical_reference_manual_en.pdf)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
ESP-Hosted
|
||||||
|
slave is the device used for its wireless (esp)
|
||||||
|
host is the master device (linux or esp)
|
||||||
|
ESP-Hosted-MCU
|
||||||
|
esp to esp
|
||||||
|
uses esp-wifi-remote under the hood
|
||||||
|
ESP-Hosted-NG
|
||||||
|
esp to linux as native device
|
||||||
|
ESP-Hosted-FG
|
||||||
|
esp to linux with some shit
|
||||||
|
ESP-Wifi-Remote (old? different)
|
||||||
|
host p4/h2 to slave esp (goes on p4/h2/master/host)
|
||||||
|
https://github.com/espressif/esp-hosted-mcu/tree/main/host
|
||||||
|
|
||||||
|
ESP-Hosted-MCU
|
||||||
|
host esp (p4/h2) using slave esp (c6/c61/c5) for wireless
|
||||||
|
https://github.com/espressif/esp-hosted-mcu/
|
||||||
|
ESP-Hosted-MCU/host
|
||||||
|
goes on host p4/h2
|
||||||
|
https://github.com/espressif/esp-hosted-mcu/tree/main/host
|
||||||
|
ESP-Hosted-MCU/slave
|
||||||
|
goes on slave esp
|
||||||
|
https://github.com/espressif/esp-hosted-mcu/tree/main/slave
|
||||||
|
ESP-Hosted-MCU/examples
|
||||||
|
test code
|
||||||
|
https://github.com/espressif/esp-hosted-mcu/tree/main/examples
|
||||||
|
|
||||||
|
When flashing slave device, esp-prog is preferred
|
||||||
|
note io0 on devkit is boot on esp-prog
|
||||||
|
|
||||||
|
devkis
|
||||||
|
c5 over sdio
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# SillyFilly Hardware Attack Tool (SFHAT)
|
||||||
|
## A hardware hacking tool made on the ESP32-P4+ESP32C5 stack
|
||||||
|
|
||||||
|
## Software
|
||||||
|
1. [ESP-IDF v5.5](https://github.com/espressif/esp-idf/tree/release/v5.5)
|
||||||
|
2. [esp-idf-tools latest](https://github.com/PrincessPi3/esp-idf-tools)
|
||||||
|
|
||||||
|
## Hardware
|
||||||
|
### Devkit WT99P4C5-S1
|
||||||
|
* [Product Page](https://en.wireless-tag.com/product-item-66.html)
|
||||||
|
* [Sale Page (Aliexpress)](https://www.aliexpress.us/item/3256809513099697.html)
|
||||||
|
|
||||||
|
## License
|
||||||
|
[](http://www.wtfpl.net/)
|
||||||
|
Distributed under the [WTFPL Version 2](http://www.wtfpl.net/)
|
||||||
|
See [assets/COPYING.txt](assets/wtfpl/COPYING.txt) for text
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
8119dac
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
3316e9d
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
|
# for disable 80211 sanity check
|
||||||
|
add_link_options("-Wl,-z,muldefs")
|
||||||
|
|
||||||
|
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||||
|
idf_build_set_property(MINIMAL_BUILD ON)
|
||||||
|
project(p4_host)
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
idf_component_register(SRCS "itwt_main.c"
|
||||||
|
"wifi_stats_cmd.c"
|
||||||
|
"wifi_itwt_cmd.c"
|
||||||
|
"disable_ieee80211_raw_frame_sanity_check.c"
|
||||||
|
PRIV_REQUIRES lwip esp_wifi esp_timer esp_pm
|
||||||
|
INCLUDE_DIRS ".")
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
menu "P4 Host Configuration"
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_SSID
|
||||||
|
string "WiFi SSID"
|
||||||
|
default "myssid"
|
||||||
|
help
|
||||||
|
SSID (network name) for the example to connect to.
|
||||||
|
|
||||||
|
config EXAMPLE_WIFI_PASSWORD
|
||||||
|
string "WiFi Password"
|
||||||
|
default "mypassword"
|
||||||
|
help
|
||||||
|
WiFi password (WPA or WPA2) for the example to use.
|
||||||
|
|
||||||
|
config EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
bool "enable static ip"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable static IP
|
||||||
|
config EXAMPLE_STATIC_IP_ADDR
|
||||||
|
string "Static IP address"
|
||||||
|
default "192.168.4.2"
|
||||||
|
depends on EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
help
|
||||||
|
Set static IP address.
|
||||||
|
|
||||||
|
config EXAMPLE_STATIC_NETMASK_ADDR
|
||||||
|
string "Static netmask address"
|
||||||
|
default "255.255.255.0"
|
||||||
|
depends on EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
help
|
||||||
|
Set static netmask address.
|
||||||
|
|
||||||
|
config EXAMPLE_STATIC_GW_ADDR
|
||||||
|
string "Static gateway address"
|
||||||
|
default "192.168.4.1"
|
||||||
|
depends on EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
help
|
||||||
|
Set static gateway address.
|
||||||
|
|
||||||
|
config EXAMPLE_TWT_ENABLE_KEEP_ALIVE_QOS_NULL
|
||||||
|
bool "enable keep alive qos null"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable send QOS NULL to keep alive during TWT.
|
||||||
|
|
||||||
|
menu "iTWT Configuration"
|
||||||
|
config EXAMPLE_ITWT_TRIGGER_ENABLE
|
||||||
|
bool "trigger-enabled"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
0- a non-trigger-enabled TWT, 1-a trigger-enabled TWT
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_ANNOUNCED
|
||||||
|
bool "announced"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
0- an unannounced TWT, 1-an announced TWT
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_MIN_WAKE_DURA
|
||||||
|
int "itwt minimum wake duration"
|
||||||
|
range 1 255
|
||||||
|
default 255
|
||||||
|
help
|
||||||
|
Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT
|
||||||
|
requesting STA expects that it needs to be awake. The value range is [1, 255].
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_WAKE_DURATION_UNIT
|
||||||
|
int "itwt wake duration unit"
|
||||||
|
range 0 1
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
TWT wake duration unit, 0: 256us 1: TU (TU = 1024us)
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_WAKE_INVL_EXPN
|
||||||
|
int "itwt wake interval exponent"
|
||||||
|
range 0 31
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
TWT Wake Interval Exponent, in microseconds. The value range is [0, 31].
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_WAKE_INVL_MANT
|
||||||
|
int "itwt wake interval mantissa"
|
||||||
|
range 1 65535
|
||||||
|
default 512
|
||||||
|
help
|
||||||
|
TWT Wake Interval Mantissa, in microseconds. The value range is [1, 65535].
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_ID
|
||||||
|
int "itwt connection id"
|
||||||
|
range 0 32767
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
TWT Connection id. The value range is [0, 32767].
|
||||||
|
|
||||||
|
config EXAMPLE_ITWT_SETUP_TIMEOUT_TIME_MS
|
||||||
|
int "itwt setup timeout times"
|
||||||
|
range 100 65535
|
||||||
|
default 5000
|
||||||
|
help
|
||||||
|
TWT setup timeout time, in microseconds. The value range is [100, 65535].
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
choice EXAMPLE_MAX_CPU_FREQ
|
||||||
|
prompt "Maximum CPU frequency"
|
||||||
|
default EXAMPLE_MAX_CPU_FREQ_96 if IDF_TARGET_ESP32H2
|
||||||
|
default EXAMPLE_MAX_CPU_FREQ_80
|
||||||
|
depends on PM_ENABLE
|
||||||
|
help
|
||||||
|
Maximum CPU frequency to use for dynamic frequency scaling.
|
||||||
|
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_96
|
||||||
|
bool "96 MHz"
|
||||||
|
depends on IDF_TARGET_ESP32H2
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_80
|
||||||
|
bool "80 MHz"
|
||||||
|
depends on !IDF_TARGET_ESP32P4
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_90
|
||||||
|
bool "90 MHz"
|
||||||
|
depends on IDF_TARGET_ESP32P4
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_120
|
||||||
|
bool "120 MHz"
|
||||||
|
depends on IDF_TARGET_ESP32C2
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_160
|
||||||
|
bool "160 MHz"
|
||||||
|
depends on !IDF_TARGET_ESP32P4
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_180
|
||||||
|
bool "180 MHz"
|
||||||
|
depends on IDF_TARGET_ESP32P4
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_240
|
||||||
|
bool "240 MHz"
|
||||||
|
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C5
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MAX_CPU_FREQ_MHZ
|
||||||
|
int
|
||||||
|
default 64 if EXAMPLE_MAX_CPU_FREQ_64
|
||||||
|
default 80 if EXAMPLE_MAX_CPU_FREQ_80
|
||||||
|
default 90 if EXAMPLE_MAX_CPU_FREQ_90
|
||||||
|
default 96 if EXAMPLE_MAX_CPU_FREQ_96
|
||||||
|
default 120 if EXAMPLE_MAX_CPU_FREQ_120
|
||||||
|
default 160 if EXAMPLE_MAX_CPU_FREQ_160
|
||||||
|
default 180 if EXAMPLE_MAX_CPU_FREQ_180
|
||||||
|
default 240 if EXAMPLE_MAX_CPU_FREQ_240
|
||||||
|
|
||||||
|
choice EXAMPLE_MIN_CPU_FREQ
|
||||||
|
prompt "Minimum CPU frequency"
|
||||||
|
default EXAMPLE_MIN_CPU_FREQ_10M if !IDF_TARGET_ESP32C5
|
||||||
|
default EXAMPLE_MIN_CPU_FREQ_12M if IDF_TARGET_ESP32C5
|
||||||
|
depends on PM_ENABLE
|
||||||
|
help
|
||||||
|
Minimum CPU frequency to use for dynamic frequency scaling.
|
||||||
|
Should be set to XTAL frequency or XTAL frequency divided by integer.
|
||||||
|
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_40M
|
||||||
|
bool "40 MHz (use with 40MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_20M
|
||||||
|
bool "20 MHz (use with 40MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_16M
|
||||||
|
bool "16 MHz (use with 32MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_32 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_12M
|
||||||
|
bool "12 MHz (use with 48MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_48 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_10M
|
||||||
|
bool "10 MHz (use with 40MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_26M
|
||||||
|
bool "26 MHz (use with 26MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_13M
|
||||||
|
bool "13 MHz (use with 26MHz XTAL)"
|
||||||
|
depends on XTAL_FREQ_26 || XTAL_FREQ_AUTO
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MIN_CPU_FREQ_MHZ
|
||||||
|
int
|
||||||
|
default 40 if EXAMPLE_MIN_CPU_FREQ_40M
|
||||||
|
default 20 if EXAMPLE_MIN_CPU_FREQ_20M
|
||||||
|
default 10 if EXAMPLE_MIN_CPU_FREQ_10M
|
||||||
|
default 26 if EXAMPLE_MIN_CPU_FREQ_26M
|
||||||
|
default 16 if EXAMPLE_MIN_CPU_FREQ_16M
|
||||||
|
default 13 if EXAMPLE_MIN_CPU_FREQ_13M
|
||||||
|
default 12 if EXAMPLE_MIN_CPU_FREQ_12M
|
||||||
|
|
||||||
|
endmenu
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// For disabling int ieee80211_raw_frame_sanity_check
|
||||||
|
// Adapted from justcallmekoko's method
|
||||||
|
// also requires add_link_options("-Wl,-z,muldefs") addded to main project CMakeLists.txt
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// For disabling int ieee80211_raw_frame_sanity_check
|
||||||
|
// Adapted from justcallmekoko's method
|
||||||
|
// also requires add_link_options("-Wl,-z,muldefs") addded to main project CMakeLists.txt
|
||||||
|
int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3);
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
dependencies:
|
||||||
|
cmd_system:
|
||||||
|
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
|
||||||
|
cmd_nvs:
|
||||||
|
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_nvs
|
||||||
|
espressif/esp_wifi_remote:
|
||||||
|
version: ">=0.10,<2.0"
|
||||||
|
rules:
|
||||||
|
- if: "target in [esp32p4, esp32h2]"
|
||||||
|
espressif/esp_hosted:
|
||||||
|
version: "*"
|
||||||
|
rules:
|
||||||
|
- if: "target in [esp32p4, esp32h2]"
|
||||||
@@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
/* itwt Example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
this example shows how to use itwt
|
||||||
|
set a router or a AP using the same SSID&PASSWORD as configuration of this example.
|
||||||
|
start esp32c6 and when it connected to AP it will setup itwt.
|
||||||
|
*/
|
||||||
|
#include <netdb.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "cmd_system.h"
|
||||||
|
#include "esp_wifi_he.h"
|
||||||
|
#include "esp_pm.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "esp_idf_version.h"
|
||||||
|
#include "wifi_cmd.h"
|
||||||
|
|
||||||
|
// For disabling int ieee80211_raw_frame_sanity_check
|
||||||
|
// Adapted from justcallmekoko's method
|
||||||
|
// also requires add_link_options("-Wl,-z,muldefs") addded to main project CMakeLists.txt
|
||||||
|
#include "disable_ieee80211_raw_frame_sanity_check.h"
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Constants
|
||||||
|
*******************************************************/
|
||||||
|
static const char *TAG = "itwt";
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Structures
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Variable Definitions
|
||||||
|
*******************************************************/
|
||||||
|
/*set the ssid and password via "idf.py menuconfig"*/
|
||||||
|
#define DEFAULT_SSID CONFIG_EXAMPLE_WIFI_SSID
|
||||||
|
#define DEFAULT_PWD CONFIG_EXAMPLE_WIFI_PASSWORD
|
||||||
|
#define ITWT_SETUP_SUCCESS 1
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_TWT_ENABLE_KEEP_ALIVE_QOS_NULL
|
||||||
|
bool keep_alive_enabled = true;
|
||||||
|
#else
|
||||||
|
bool keep_alive_enabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_ITWT_TRIGGER_ENABLE
|
||||||
|
uint8_t trigger_enabled = 1;
|
||||||
|
#else
|
||||||
|
uint8_t trigger_enabled = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_ITWT_ANNOUNCED
|
||||||
|
uint8_t flow_type_announced = 1;
|
||||||
|
#else
|
||||||
|
uint8_t flow_type_announced = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_netif_t *netif_sta = NULL;
|
||||||
|
const int CONNECTED_BIT = BIT0;
|
||||||
|
const int DISCONNECTED_BIT = BIT1;
|
||||||
|
EventGroupHandle_t wifi_event_group;
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Declarations
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Definitions
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
static void example_set_static_ip(esp_netif_t *netif)
|
||||||
|
{
|
||||||
|
#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
if (esp_netif_dhcpc_stop(netif) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to stop dhcp client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
esp_netif_ip_info_t ip;
|
||||||
|
memset(&ip, 0 , sizeof(esp_netif_ip_info_t));
|
||||||
|
ip.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_IP_ADDR);
|
||||||
|
ip.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_NETMASK_ADDR);
|
||||||
|
ip.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_STATIC_GW_ADDR);
|
||||||
|
if (esp_netif_set_ip_info(netif, &ip) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Failed to set ip info");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "Success to set static ip: %s, netmask: %s, gw: %s",
|
||||||
|
CONFIG_EXAMPLE_STATIC_IP_ADDR, CONFIG_EXAMPLE_STATIC_NETMASK_ADDR, CONFIG_EXAMPLE_STATIC_GW_ADDR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *itwt_probe_status_to_str(wifi_itwt_probe_status_t status)
|
||||||
|
{
|
||||||
|
switch (status) {
|
||||||
|
case ITWT_PROBE_FAIL: return "itwt probe fail";
|
||||||
|
case ITWT_PROBE_SUCCESS: return "itwt probe success";
|
||||||
|
case ITWT_PROBE_TIMEOUT: return "itwt probe timeout";
|
||||||
|
case ITWT_PROBE_STA_DISCONNECTED: return "Sta disconnected";
|
||||||
|
default: return "Unknown status";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void got_ip_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
xEventGroupClearBits(wifi_event_group, DISCONNECTED_BIT);
|
||||||
|
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||||
|
|
||||||
|
/* setup a trigger-based announce individual TWT agreement. */
|
||||||
|
wifi_phy_mode_t phymode;
|
||||||
|
wifi_config_t sta_cfg = { 0, };
|
||||||
|
esp_wifi_get_config(WIFI_IF_STA, &sta_cfg);
|
||||||
|
esp_wifi_sta_get_negotiated_phymode(&phymode);
|
||||||
|
if (phymode == WIFI_PHY_MODE_HE20) {
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||||
|
wifi_itwt_setup_config_t setup_config
|
||||||
|
#else
|
||||||
|
// wifi_itwt_setup_config_t only found in IDF v5.3.1 and above
|
||||||
|
wifi_twt_setup_config_t setup_config
|
||||||
|
#endif
|
||||||
|
= {
|
||||||
|
.setup_cmd = TWT_REQUEST,
|
||||||
|
.flow_id = 0,
|
||||||
|
.twt_id = CONFIG_EXAMPLE_ITWT_ID,
|
||||||
|
.flow_type = flow_type_announced ? 0 : 1,
|
||||||
|
.min_wake_dura = CONFIG_EXAMPLE_ITWT_MIN_WAKE_DURA,
|
||||||
|
.wake_duration_unit = CONFIG_EXAMPLE_ITWT_WAKE_DURATION_UNIT,
|
||||||
|
.wake_invl_expn = CONFIG_EXAMPLE_ITWT_WAKE_INVL_EXPN,
|
||||||
|
.wake_invl_mant = CONFIG_EXAMPLE_ITWT_WAKE_INVL_MANT,
|
||||||
|
.trigger = trigger_enabled,
|
||||||
|
.timeout_time_ms = CONFIG_EXAMPLE_ITWT_SETUP_TIMEOUT_TIME_MS,
|
||||||
|
};
|
||||||
|
err = esp_wifi_sta_itwt_setup(&setup_config);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "itwt setup failed, err:0x%x", err);
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Must be in 11ax mode to support itwt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "sta connect to %s", DEFAULT_SSID);
|
||||||
|
esp_wifi_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disconnect_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "sta disconnect, reconnect...");
|
||||||
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||||
|
esp_wifi_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void itwt_setup_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
wifi_event_sta_itwt_setup_t *setup = (wifi_event_sta_itwt_setup_t *) event_data;
|
||||||
|
if (setup->status == ITWT_SETUP_SUCCESS) {
|
||||||
|
/* TWT Wake Interval = TWT Wake Interval Mantissa * (2 ^ TWT Wake Interval Exponent) */
|
||||||
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>twt_id:%d, flow_id:%d, %s, %s, wake_dura:%d, wake_dura_unit:%d, wake_invl_e:%d, wake_invl_m:%d", setup->config.twt_id,
|
||||||
|
setup->config.flow_id, setup->config.trigger ? "trigger-enabled" : "non-trigger-enabled", setup->config.flow_type ? "unannounced" : "announced",
|
||||||
|
setup->config.min_wake_dura, setup->config.wake_duration_unit, setup->config.wake_invl_expn, setup->config.wake_invl_mant);
|
||||||
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SETUP>target wake time:%lld, wake duration:%d us, service period:%d us", setup->target_wake_time, setup->config.min_wake_dura << (setup->config.wake_duration_unit == 1 ? 10 : 8),
|
||||||
|
setup->config.wake_invl_mant << setup->config.wake_invl_expn);
|
||||||
|
} else {
|
||||||
|
if (setup->status == ESP_ERR_WIFI_TWT_SETUP_TIMEOUT) {
|
||||||
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>twt_id:%d, timeout of receiving twt setup response frame", setup->config.twt_id);
|
||||||
|
} else if (setup->status == ESP_ERR_WIFI_TWT_SETUP_TXFAIL) {
|
||||||
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup frame tx failed, reason: %d", setup->config.twt_id, setup->reason);
|
||||||
|
} else if (setup->status == ESP_ERR_WIFI_TWT_SETUP_REJECT) {
|
||||||
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup request was rejected, setup cmd: %d", setup->config.twt_id, setup->config.setup_cmd);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_SETUP>twt_id:%d, twt setup failed, status: %d", setup->config.twt_id, setup->status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void itwt_teardown_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
wifi_event_sta_itwt_teardown_t *teardown = (wifi_event_sta_itwt_teardown_t *) event_data;
|
||||||
|
if (teardown->status == ITWT_TEARDOWN_FAIL) {
|
||||||
|
ESP_LOGE(TAG, "<WIFI_EVENT_ITWT_TEARDOWN>flow_id %d%s, twt teardown frame tx failed", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : "");
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_TEARDOWN>flow_id %d%s", teardown->flow_id, (teardown->flow_id == 8) ? "(all twt)" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void itwt_suspend_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
wifi_event_sta_itwt_suspend_t *suspend = (wifi_event_sta_itwt_suspend_t *) event_data;
|
||||||
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_SUSPEND>status:%d, flow_id_bitmap:0x%x, actual_suspend_time_ms:[%lu %lu %lu %lu %lu %lu %lu %lu]",
|
||||||
|
suspend->status, suspend->flow_id_bitmap,
|
||||||
|
suspend->actual_suspend_time_ms[0], suspend->actual_suspend_time_ms[1], suspend->actual_suspend_time_ms[2], suspend->actual_suspend_time_ms[3],
|
||||||
|
suspend->actual_suspend_time_ms[4], suspend->actual_suspend_time_ms[5], suspend->actual_suspend_time_ms[6], suspend->actual_suspend_time_ms[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void itwt_probe_handler(void *arg, esp_event_base_t event_base,
|
||||||
|
int32_t event_id, void *event_data)
|
||||||
|
{
|
||||||
|
wifi_event_sta_itwt_probe_t *probe = (wifi_event_sta_itwt_probe_t *) event_data;
|
||||||
|
ESP_LOGI(TAG, "<WIFI_EVENT_ITWT_PROBE>status:%s, reason:0x%x", itwt_probe_status_to_str(probe->status), probe->reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wifi_itwt(void)
|
||||||
|
{
|
||||||
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
|
wifi_event_group = xEventGroupCreate();
|
||||||
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
|
netif_sta = esp_netif_create_default_wifi_sta();
|
||||||
|
assert(netif_sta);
|
||||||
|
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_STA_START,
|
||||||
|
&start_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_STA_DISCONNECTED,
|
||||||
|
&disconnect_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
|
||||||
|
IP_EVENT_STA_GOT_IP,
|
||||||
|
&got_ip_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
/* itwt */
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_ITWT_SETUP,
|
||||||
|
&itwt_setup_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_ITWT_TEARDOWN,
|
||||||
|
&itwt_teardown_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_ITWT_SUSPEND,
|
||||||
|
&itwt_suspend_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
|
WIFI_EVENT_ITWT_PROBE,
|
||||||
|
&itwt_probe_handler,
|
||||||
|
NULL,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
wifi_config_t wifi_config = {
|
||||||
|
.sta = {
|
||||||
|
.ssid = DEFAULT_SSID,
|
||||||
|
.password = DEFAULT_PWD,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 0)
|
||||||
|
wifi_twt_config_t wifi_twt_config = {
|
||||||
|
.post_wakeup_event = false,
|
||||||
|
#if ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 3, 1)
|
||||||
|
// twt_enable_keep_alive only found in IDF v5.3.2 and above
|
||||||
|
.twt_enable_keep_alive = keep_alive_enabled,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
// esp_wifi_sta_twt_config only found in IDF v5.3.1 and above
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_sta_twt_config(&wifi_twt_config));
|
||||||
|
#endif
|
||||||
|
#if CONFIG_SOC_WIFI_SUPPORT_5G || CONFIG_SLAVE_SOC_WIFI_SUPPORT_5G
|
||||||
|
wifi_bandwidths_t bw = {
|
||||||
|
.ghz_2g = WIFI_BW_HT20,
|
||||||
|
.ghz_5g = WIFI_BW_HT20,
|
||||||
|
};
|
||||||
|
esp_wifi_set_bandwidths(WIFI_IF_STA, &bw);
|
||||||
|
|
||||||
|
wifi_protocols_t protocol = {
|
||||||
|
.ghz_2g = WIFI_PROTOCOL_11AX,
|
||||||
|
.ghz_5g = WIFI_PROTOCOL_11AX,
|
||||||
|
};
|
||||||
|
esp_wifi_set_protocols(WIFI_IF_STA, &protocol);
|
||||||
|
#else
|
||||||
|
esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT20);
|
||||||
|
esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N | WIFI_PROTOCOL_11AX);
|
||||||
|
#endif
|
||||||
|
esp_wifi_set_ps(WIFI_PS_MIN_MODEM);
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_ENABLE_STATIC_IP
|
||||||
|
example_set_static_ip(netif_sta);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_wifi_start());
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||||
|
esp_wifi_enable_rx_statistics(true, true);
|
||||||
|
#else
|
||||||
|
esp_wifi_enable_rx_statistics(true, false);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||||
|
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_VO, true); //VO, mgmt
|
||||||
|
esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //BE, data
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
// Initialize NVS
|
||||||
|
esp_err_t ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
|
// Configure dynamic frequency scaling:
|
||||||
|
// maximum and minimum frequencies are set in sdkconfig,
|
||||||
|
// automatic light sleep is enabled if tickless idle support is enabled.
|
||||||
|
esp_pm_config_t pm_config = {
|
||||||
|
.max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
|
||||||
|
.min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,
|
||||||
|
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
|
||||||
|
// SDIO currently does not work with auto light sleep
|
||||||
|
//.light_sleep_enable = true
|
||||||
|
.light_sleep_enable = false
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
|
||||||
|
ESP_ERROR_CHECK( ret );
|
||||||
|
|
||||||
|
#else
|
||||||
|
printf("\n =================================================\n");
|
||||||
|
printf(" | Test WiFi 6 itwt |\n");
|
||||||
|
printf(" =================================================\n\n");
|
||||||
|
|
||||||
|
esp_console_repl_t *repl = NULL;
|
||||||
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
repl_config.prompt = "itwt>";
|
||||||
|
|
||||||
|
// init console REPL environment
|
||||||
|
#if CONFIG_ESP_CONSOLE_UART
|
||||||
|
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_CDC
|
||||||
|
esp_console_dev_usb_cdc_config_t cdc_config = ESP_CONSOLE_DEV_CDC_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_cdc(&cdc_config, &repl_config, &repl));
|
||||||
|
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||||
|
esp_console_dev_usb_serial_jtag_config_t usbjtag_config = ESP_CONSOLE_DEV_USB_SERIAL_JTAG_CONFIG_DEFAULT();
|
||||||
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// start console REPL
|
||||||
|
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//start wifi
|
||||||
|
wifi_itwt();
|
||||||
|
// register commands
|
||||||
|
register_system();
|
||||||
|
register_wifi_itwt();
|
||||||
|
register_wifi_stats();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void register_wifi_itwt(void);
|
||||||
|
void register_wifi_stats(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
|
#if CONFIG_SOC_WIFI_HE_SUPPORT || CONFIG_SLAVE_SOC_WIFI_HE_SUPPORT
|
||||||
|
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_wifi_he.h"
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Constants
|
||||||
|
*******************************************************/
|
||||||
|
static const char *TAG = "twt";
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Structures
|
||||||
|
*******************************************************/
|
||||||
|
typedef struct {
|
||||||
|
struct arg_int *setup;
|
||||||
|
struct arg_lit *teardown;
|
||||||
|
struct arg_lit *suspend;
|
||||||
|
struct arg_lit *getflowid;
|
||||||
|
struct arg_int *waketimeoffset;
|
||||||
|
struct arg_int *trigger; //1-trigger-enabled, 0-non-trigger-enabled, setup
|
||||||
|
struct arg_int *flowtype; //1-unannounced, 0-announced, setup
|
||||||
|
struct arg_int *negtype;
|
||||||
|
struct arg_int *wakeinvlexp; //setup
|
||||||
|
struct arg_int *wakeduraunit; //1-TU, 0-256us
|
||||||
|
struct arg_int *wakeinvlman; //setup
|
||||||
|
struct arg_int *minwakedur; //setup
|
||||||
|
struct arg_int *flowid;
|
||||||
|
struct arg_int *twtid;
|
||||||
|
struct arg_int *setup_timeout_time_ms;
|
||||||
|
struct arg_int *suspend_time_ms;
|
||||||
|
struct arg_int *all_twt;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_itwt_args_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct arg_int *timeout;
|
||||||
|
struct arg_end *end;
|
||||||
|
} wifi_itwt_send_probereq_t;
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Variable Definitions
|
||||||
|
*******************************************************/
|
||||||
|
static wifi_itwt_args_t itwt_args;
|
||||||
|
static wifi_itwt_send_probereq_t itwt_probe_args;
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Declarations
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Definitions
|
||||||
|
*******************************************************/
|
||||||
|
static int wifi_cmd_itwt(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &itwt_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, itwt_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
if (itwt_args.setup->count) {
|
||||||
|
if (itwt_args.wakeinvlman->count) {
|
||||||
|
if (itwt_args.wakeinvlman->ival[0] < 0 || itwt_args.wakeinvlman->ival[0] > 65535) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 65535], wake_invl_mant: %d", itwt_args.wakeinvlman->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.wakeinvlexp->count) {
|
||||||
|
if (itwt_args.wakeinvlexp->ival[0] < 0 || itwt_args.wakeinvlexp->ival[0] > 31) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 31], wake_invl_expn: %d", itwt_args.wakeinvlexp->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.minwakedur->count) {
|
||||||
|
if (itwt_args.minwakedur->ival[0] < 0 || itwt_args.minwakedur->ival[0] > 255) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 255], min_wake_dura: %d", itwt_args.minwakedur->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.wakeduraunit->count) {
|
||||||
|
if (itwt_args.wakeduraunit->ival[0] < 0 || itwt_args.wakeduraunit->ival[0] > 1) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 1], wake duration unit: %d", itwt_args.wakeduraunit->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.twtid->count) {
|
||||||
|
if (itwt_args.twtid->ival[0] < 0 || itwt_args.twtid->ival[0] > 32767) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 32767], twt id: %d", itwt_args.twtid->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.setup_timeout_time_ms->count) {
|
||||||
|
if (itwt_args.setup_timeout_time_ms->ival[0] < 0 || itwt_args.setup_timeout_time_ms->ival[0] > 65535) {
|
||||||
|
ESP_LOGE(TAG, "(itwt)expect [0, 65535], setup timeout time: %d", itwt_args.setup_timeout_time_ms->ival[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wifi_twt_setup_config_t setup_config = {
|
||||||
|
.setup_cmd = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST,
|
||||||
|
.flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : 0,
|
||||||
|
.twt_id = itwt_args.twtid->count ? itwt_args.twtid->ival[0] : 0,
|
||||||
|
.flow_type = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0,
|
||||||
|
.min_wake_dura = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255,
|
||||||
|
.wake_duration_unit = itwt_args.wakeduraunit->count ? itwt_args.wakeduraunit->ival[0] : 0,
|
||||||
|
.wake_invl_expn = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10,
|
||||||
|
.wake_invl_mant = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512,
|
||||||
|
.trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? 1 : 0) : 1,
|
||||||
|
.timeout_time_ms = itwt_args.setup_timeout_time_ms->count ? itwt_args.setup_timeout_time_ms->ival[0] : 5000,
|
||||||
|
};
|
||||||
|
err = esp_wifi_sta_itwt_setup(&setup_config);
|
||||||
|
ESP_LOGI(TAG, "(itwt)setup, trigger:%d, %s, flow_id:%d, err:0x%x",
|
||||||
|
setup_config.trigger, setup_config.flow_type ? "unannounce" : "announced", setup_config.flow_id, err);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.teardown->count) {
|
||||||
|
// teardown a given flow id, all_twt has a high priority
|
||||||
|
int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1);
|
||||||
|
bool all_twt = itwt_args.all_twt->count ? ((itwt_args.all_twt->ival[0] == 1) ? true : false) : false;
|
||||||
|
flow_id = (all_twt == true) ? FLOW_ID_ALL : flow_id;
|
||||||
|
ESP_LOGW(TAG, "flow_id %d", flow_id);
|
||||||
|
if (flow_id >= 0) {
|
||||||
|
err = esp_wifi_sta_itwt_teardown(flow_id);
|
||||||
|
ESP_LOGI(TAG, "(itwt)teardown, flow_id:%d, all_twt:%d, err:0x%x", flow_id, all_twt, err);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "(itwt)teardown, should specify an existing flow id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.suspend->count) {
|
||||||
|
// suspend a given flow id
|
||||||
|
int flow_id = itwt_args.flowid->count ? itwt_args.flowid->ival[0] : (-1);
|
||||||
|
bool all_twt = itwt_args.all_twt->count ? (itwt_args.all_twt->ival[0] ? true : false) : false;
|
||||||
|
flow_id = (all_twt == true) ? FLOW_ID_ALL : flow_id;
|
||||||
|
int suspend_time_ms = itwt_args.suspend_time_ms->count ? itwt_args.suspend_time_ms->ival[0] : 0;
|
||||||
|
if (flow_id >= 0) {
|
||||||
|
err = esp_wifi_sta_itwt_suspend(flow_id, suspend_time_ms);
|
||||||
|
ESP_LOGI(TAG, "(itwt)suspend, flow_id:%d, all_twt:%d, suspend:%d ms, err:0x%x", flow_id, all_twt, suspend_time_ms, err);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "(itwt)suspend, should specify an existing flow id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.getflowid->count) {
|
||||||
|
int flow_id_bitmap;
|
||||||
|
err = esp_wifi_sta_itwt_get_flow_id_status(&flow_id_bitmap);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
ESP_LOGI(TAG, "flowid bitmap: 0x%" PRIx16, flow_id_bitmap);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itwt_args.waketimeoffset->count) {
|
||||||
|
int offset_us = itwt_args.waketimeoffset->ival[0];
|
||||||
|
err = esp_wifi_sta_itwt_set_target_wake_time_offset(offset_us);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wifi_cmd_itwt_probe(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int nerrors = arg_parse(argc, argv, (void **) &itwt_probe_args);
|
||||||
|
if (nerrors != 0) {
|
||||||
|
arg_print_errors(stderr, itwt_probe_args.end, argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
if (itwt_probe_args.timeout->count) {
|
||||||
|
if (itwt_probe_args.timeout->ival[0] > 0) {
|
||||||
|
ESP_LOGI(TAG, "(itwt)send probe req, timeout:%d ms", itwt_probe_args.timeout->ival[0]);
|
||||||
|
err = esp_wifi_sta_itwt_send_probe_req(itwt_probe_args.timeout->ival[0]);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Error: %s", esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "(itwt)invalid input, timeout:%d ms", itwt_probe_args.timeout->ival[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "err:0x%x", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_wifi_itwt(void)
|
||||||
|
{
|
||||||
|
/* itwt setup/teardown */
|
||||||
|
itwt_args.setup = arg_int0(NULL, "setup", "<setup>", "twt setup/teardown an individual flow id");
|
||||||
|
itwt_args.teardown = arg_lit0(NULL, "teardown", "twt setup/teardown an individual flow id");
|
||||||
|
itwt_args.suspend = arg_lit0(NULL, "suspend", "twt setup/teardown an individual flow id");
|
||||||
|
itwt_args.getflowid = arg_lit0(NULL, "getflowid", "get flow ids");
|
||||||
|
itwt_args.waketimeoffset = arg_int0(NULL, "waketimeoffset", "<offset us>", "set wake time offset (in us)");
|
||||||
|
itwt_args.trigger = arg_int0("t", NULL, "<trigger>", "trigger");
|
||||||
|
itwt_args.flowtype = arg_int0("f", NULL, "<flow_type>", "flow type: 0-announced, 1-unannounced");
|
||||||
|
itwt_args.negtype = arg_int0("n", NULL, "<neg_type>", "negotiate type");
|
||||||
|
itwt_args.minwakedur = arg_int0("d", NULL, "<minwakedur>", "Norminal Min. Wake Duration");
|
||||||
|
itwt_args.wakeduraunit = arg_int0("u", NULL, "<wakeduraunit>", "wake duration unit 0-256us, 1-TU (TU = 1024us)");
|
||||||
|
itwt_args.wakeinvlexp = arg_int0("e", NULL, "<wakeinvlexp>", "Wake Interval Exponent");
|
||||||
|
itwt_args.wakeinvlman = arg_int0("m", NULL, "<wakeinvlman>", "Wake Interval Mantissa");
|
||||||
|
itwt_args.flowid = arg_int0("i", NULL, "<flow_id>", "Flow ID");
|
||||||
|
itwt_args.suspend_time_ms = arg_int0("s", NULL, "<suspend_time_ms>", "time of suspending iTWT agreements, unit ms");
|
||||||
|
itwt_args.twtid = arg_int0("w", NULL, "<twt_id>", "TWT ID");
|
||||||
|
itwt_args.setup_timeout_time_ms = arg_int0("u", NULL, "<setup_timeout_time_ms>", "iTWT setup timeout time, unit ms");
|
||||||
|
itwt_args.all_twt = arg_int0("a", NULL, "<all_twt>", "All TWT");
|
||||||
|
itwt_args.end = arg_end(1);
|
||||||
|
const esp_console_cmd_t itwt_cmd = {
|
||||||
|
.command = "itwt",
|
||||||
|
.help = "itwt setup, teardown or suspend",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_itwt,
|
||||||
|
.argtable = &itwt_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_cmd));
|
||||||
|
|
||||||
|
/* itwt probe */
|
||||||
|
itwt_probe_args.timeout = arg_int0("t", NULL, "[timeout]", "time of sending a probe request frame and receiving a probe response frame from ap, unit ms");
|
||||||
|
itwt_probe_args.end = arg_end(1);
|
||||||
|
const esp_console_cmd_t itwt_probe_cmd = {
|
||||||
|
.command = "probe",
|
||||||
|
.help = "send probe request for TSF update when at lease one itwt agreement setup",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_itwt_probe,
|
||||||
|
.argtable = &itwt_probe_args
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&itwt_probe_cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void register_wifi_itwt(void)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_SOC_WIFI_HE_SUPPORT || CONFIG_SLAVE_SOC_WIFI_HE_SUPPORT */
|
||||||
@@ -0,0 +1,584 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||||
|
|
||||||
|
#include "esp_console.h"
|
||||||
|
#include "argtable3/argtable3.h"
|
||||||
|
#include "esp_event.h"
|
||||||
|
#include "esp_wifi.h"
|
||||||
|
#include "esp_wifi_types.h"
|
||||||
|
#include "esp_private/esp_wifi_he_private.h"
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Macros
|
||||||
|
*******************************************************/
|
||||||
|
/*
|
||||||
|
* enable/disable rx/tx statistics after Wi-Fi started:
|
||||||
|
* (1) esp_wifi_enable_rx_statistics(true, true); //rx_stats=true, rx_mu_stats=true
|
||||||
|
* (2) esp_wifi_enable_tx_statistics(ESP_WIFI_ACI_BE, true); //aci=ESP_WIFI_ACI_BE, tx_stats=true
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Constants
|
||||||
|
*******************************************************/
|
||||||
|
static const char *TAG = "stats";
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Structures
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Variable Definitions
|
||||||
|
*******************************************************/
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||||
|
esp_test_rx_mu_statistics_t rx_mu_stats = { 0, }; //10932 bytes
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Declarations
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Function Definitions
|
||||||
|
*******************************************************/
|
||||||
|
const char *tx_fail_error2str(esp_test_tx_fail_error_t error)
|
||||||
|
{
|
||||||
|
switch (error) {
|
||||||
|
case TEST_TX_FAIL_ERROR_H00:
|
||||||
|
return "0x00";
|
||||||
|
case TEST_TX_FAIL_ERROR_H53:
|
||||||
|
return "0x53";
|
||||||
|
case TEST_TX_FAIL_ERROR_H63:
|
||||||
|
return "0x63";
|
||||||
|
case TEST_TX_FAIL_ERROR_H75:
|
||||||
|
return "0x75";
|
||||||
|
case TEST_TX_FAIL_ERROR_H41:
|
||||||
|
return "0x41";
|
||||||
|
case TEST_TX_FAIL_ERROR_H42:
|
||||||
|
return "0x42";
|
||||||
|
case TEST_TX_FAIL_ERROR_H47:
|
||||||
|
return "0x47";
|
||||||
|
case TEST_TX_FAIL_ERROR_H80:
|
||||||
|
return "0x80";
|
||||||
|
case TEST_TX_FAIL_ERROR_H5A:
|
||||||
|
return "0x5A";
|
||||||
|
case TEST_TX_FAIL_ERROR_HXX:
|
||||||
|
return "Others";
|
||||||
|
case TEST_TX_FAIL_ERROR_MAX:
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *tx_fail_match2str(esp_test_tx_fail_match_t match)
|
||||||
|
{
|
||||||
|
switch (match) {
|
||||||
|
case TEST_TX_WAIT_MATCH:
|
||||||
|
return "MATCH";
|
||||||
|
case TEST_TX_WAIT_NOT2SELF:
|
||||||
|
return "NOT2SELF";
|
||||||
|
case TEST_TX_MISMATCH:
|
||||||
|
return "MISMATCH";
|
||||||
|
case TEST_TX_WAIT_TIMEOUT:
|
||||||
|
return "TIMEOUT";
|
||||||
|
case TEST_TX_WAIT_MAX:
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *tx_fail_state2str(esp_test_tx_fail_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case TEST_TX_SUCCESS:
|
||||||
|
return "TX Success";
|
||||||
|
case TEST_TX_FAIL_RTS:
|
||||||
|
return "TX RTS";
|
||||||
|
case TEST_TX_WAIT_CTS: //RX
|
||||||
|
return "Wait CTS";
|
||||||
|
case TEST_TX_FAIL_CTS:
|
||||||
|
return "TX RTS";
|
||||||
|
case TEST_TX_FAIL_DATA:
|
||||||
|
return "TX DATA";
|
||||||
|
case TEST_TX_WAIT_ACK: //RX
|
||||||
|
return "Wait ACK/BA";
|
||||||
|
case TEST_TX_FAIL_MAX:
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
return "Undefined";
|
||||||
|
}
|
||||||
|
|
||||||
|
int wifi_cmd_clr_tx_statistics(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Clear tx statistics");
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
esp_wifi_clr_tx_statistics(i); //BE
|
||||||
|
esp_wifi_clr_tx_tb_statistics(i);
|
||||||
|
}
|
||||||
|
esp_test_clr_hw_statistics();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_hw_tb_statistics(void)
|
||||||
|
{
|
||||||
|
esp_test_hw_tb_statistics_t hw_tb_stats = { 0, };
|
||||||
|
esp_test_get_hw_tb_statistics(&hw_tb_stats);
|
||||||
|
printf("(test)rx_trig:%d, tx_bfrpt:%d, tb_times:%d, tb_qos_null:%d, tb_qos_data:%d, tb_cca_cancel:%d, tb_sifs_abort:%d, tb_pwr_outof_range:%d\n",
|
||||||
|
hw_tb_stats.rx_trig,
|
||||||
|
hw_tb_stats.tx_bfrpt, //including TB and Non-TB
|
||||||
|
hw_tb_stats.tb_times,
|
||||||
|
hw_tb_stats.tb_qos_null,
|
||||||
|
hw_tb_stats.tb_times - hw_tb_stats.tb_qos_null,
|
||||||
|
hw_tb_stats.tb_cca_cancel,
|
||||||
|
hw_tb_stats.tb_sifs_abort,
|
||||||
|
hw_tb_stats.tb_pwr_outof_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wifi_cmd_get_tx_statistics(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint8_t i, h, j, k;
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "Get tx statistics");
|
||||||
|
esp_test_tx_tb_statistics_t tb_stats = { 0, }; //32 bytes
|
||||||
|
esp_test_tx_statistics_t tx_stats = { 0, }; //136 bytes
|
||||||
|
esp_test_tx_fail_statistics_t tx_fail[TEST_TX_FAIL_MAX] = { 0, }; //TEST_TX_FAIL_MAX * 164 bytes
|
||||||
|
|
||||||
|
print_hw_tb_statistics();
|
||||||
|
//only check BE
|
||||||
|
for (i = 2; i < 3; i++) {
|
||||||
|
esp_wifi_get_tx_tb_statistics(i, &tb_stats);
|
||||||
|
/* TB */
|
||||||
|
printf("(test)aci:%" PRIu8 ", tb(suc:%" PRIu32 ", ack:%" PRIu32 ", err:%" PRIu32 "), "
|
||||||
|
"count(suc:%" PRIu32 ", ack:%" PRIu32 ", err:%" PRIu32 ", tot:%" PRIu32 ", max_sent:%" PRIu32 ")\n",
|
||||||
|
i,
|
||||||
|
tb_stats.complete_suc_tb,
|
||||||
|
tb_stats.complete_ack_tb,
|
||||||
|
tb_stats.complete_err_tb,
|
||||||
|
tb_stats.complete_tb_suc_count,
|
||||||
|
tb_stats.complete_tb_ack_count,
|
||||||
|
tb_stats.complete_tb_err_count,
|
||||||
|
tb_stats.complete_tb_tot_count,
|
||||||
|
tb_stats.complete_tb_pack_sent);
|
||||||
|
|
||||||
|
esp_wifi_get_tx_statistics(i, &tx_stats, (esp_test_tx_fail_statistics_t *) &tx_fail);
|
||||||
|
int tot_tx_times = tx_stats.tb_times + (tx_stats.tx_enable - tx_stats.tb_last); //TB + EDCA
|
||||||
|
int tot_fail = tx_fail[1].count + tx_fail[2].count + tx_fail[3].count + tx_fail[4].count + tx_fail[5].count;
|
||||||
|
printf("(test)aci:%" PRIu8 ", enable:%" PRIu32 ", complete:%" PRIu32 ", tb_times:%" PRIu32 ", tb_last:%" PRIu32 ", edca:%" PRIu32 ", "
|
||||||
|
"succ:%" PRIu32 ", fail(%" PRIu32 ",%" PRIu32 ",%" PRIu32 ", cts:%" PRIu32 "/%2.2f%%, ack:%" PRIu32 "/%2.2f%%, tot:%d, %.2f%%), "
|
||||||
|
"edca(ack:%" PRIu32 ", ba:%" PRIu32 "), tb(hw-ba:%" PRIu32 ", sw-ba:%" PRIu32 ")\n",
|
||||||
|
i, tx_stats.tx_enable,
|
||||||
|
tx_stats.tx_complete,
|
||||||
|
tx_stats.tb_times,
|
||||||
|
tx_stats.tb_last,
|
||||||
|
tx_stats.tx_enable - tx_stats.tb_last,
|
||||||
|
tx_fail[0].count,
|
||||||
|
tx_fail[1].count,
|
||||||
|
tx_fail[3].count,
|
||||||
|
tx_fail[4].count,
|
||||||
|
tx_fail[2].count,
|
||||||
|
(float) ((float) tx_fail[2].count / (float) tot_tx_times) * 100, //rx cts
|
||||||
|
tx_fail[5].count, (float) ((float) tx_fail[5].count / (float) tot_tx_times) * 100, //rx ack
|
||||||
|
tot_fail,
|
||||||
|
(float) ((float) tot_fail / (float) tot_tx_times) * 100,
|
||||||
|
tx_stats.rx_ack,
|
||||||
|
tx_stats.rx_ba,
|
||||||
|
tx_stats.tb_rx_ba, //including ACKs
|
||||||
|
tx_stats.rx_dump_ba);
|
||||||
|
|
||||||
|
printf("(test)aci:%" PRIu8 ", txFrames:%" PRIu32 ", s-mpdu:%" PRIu32 "(%.2f%%), "
|
||||||
|
"bitmap(max:%d, min:%d, tot:%" PRIu32 ", avg:%.2f), "
|
||||||
|
"retry(edca:%" PRIu32 ", tb:%" PRIu32 ", %.2f%%), collision:%" PRIu32 ", timeout:%" PRIu32 "\n",
|
||||||
|
i,
|
||||||
|
tx_stats.tx_succ,
|
||||||
|
tx_stats.rx_ack,
|
||||||
|
((float) (tx_stats.rx_ack) / (float) tot_tx_times) * 100,
|
||||||
|
tx_stats.rx_max_bitmap,
|
||||||
|
tx_stats.rx_min_bitmap,
|
||||||
|
tx_stats.rx_tot_bitmap,
|
||||||
|
(float) tx_stats.rx_tot_bitmap / (float) (tx_stats.tb_rx_ba + tx_stats.rx_ba),
|
||||||
|
tx_stats.retry_edca, tx_stats.retry_tb, (float) (tx_stats.retry_edca + tx_stats.retry_tb) / (float) tx_stats.tx_succ * 100,
|
||||||
|
tx_stats.collision, tx_stats.timeout);
|
||||||
|
|
||||||
|
float tot_rtt_ms = (float) tx_stats.tx_tot_rtt / (float) 1000;
|
||||||
|
printf("(test)aci:%" PRIu8 ", seqno_rtt[%" PRIu32 ",%" PRIu32 "], hw_rtt[%" PRIu32 ", %" PRIu32 "], muedca[enable:%" PRIu32 ", times:%" PRIu32 ", %.2f, %.2f, tot:%.2f], avg:%.3f ms, tot:%.3f secs\n",
|
||||||
|
i,
|
||||||
|
tx_stats.tx_seq_min_rtt,
|
||||||
|
tx_stats.tx_seq_max_rtt,
|
||||||
|
tx_stats.tx_min_rtt,
|
||||||
|
tx_stats.tx_max_rtt,
|
||||||
|
tx_stats.tx_muedca_enable,
|
||||||
|
tx_stats.muedca_times,
|
||||||
|
(float) tx_stats.tx_min_muedca_time / (float) 1000,
|
||||||
|
(float) tx_stats.tx_max_muedca_time / (float) 1000,
|
||||||
|
(float) tx_stats.tx_tot_muedca_time / (float) 1000, //ms
|
||||||
|
(float) tot_rtt_ms / (float) tot_tx_times, //ms
|
||||||
|
(float) tot_rtt_ms / (float) 1000); //seconds
|
||||||
|
/* fail state */
|
||||||
|
for (h = 1; h < TEST_TX_FAIL_MAX; h++) { //state
|
||||||
|
for (j = 0; j < TEST_TX_WAIT_MAX; j++) { //match
|
||||||
|
for (k = 0; k < TEST_TX_FAIL_ERROR_MAX; k++) { //error
|
||||||
|
if (tx_fail[h].match[j][k]) {
|
||||||
|
printf("(test)[%d][%d][%d](%16s + %16s + %16s)%3" PRIu32 "/%3" PRIu32 "(%.2f%%)\n", h, j, k, tx_fail_state2str(h),
|
||||||
|
tx_fail_match2str(j), tx_fail_error2str(k),
|
||||||
|
tx_fail[h].match[j][k], tx_fail[h].count,
|
||||||
|
((float) tx_fail[h].match[j][k] / (float) tx_fail[h].count) * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
wifi_cmd_clr_tx_statistics(0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_rx_statistics_nonmimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
||||||
|
{
|
||||||
|
if (!mu_stats->nonmimo_rx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
int tot_rx_nonmimo = 0;
|
||||||
|
ESP_LOGW(TAG, "(nonmimo)dut rx:%" PRIu32, mu_stats->nonmimo_rx);
|
||||||
|
ESP_LOGW(TAG, "(nonmimo)ru_alloc_96_num_2046:%" PRIu32 ", ru_alloc_112_num_2046:%" PRIu32, mu_stats->ru_alloc_96_num_2046, mu_stats->ru_alloc_112_num_2046);
|
||||||
|
ESP_LOGW(TAG, "(nonmimo)sigb, mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), mcs5:%" PRIu32 "(%2.2f%%)",
|
||||||
|
mu_stats->nonmimo_sigb_mcs[0], ((float) mu_stats->nonmimo_sigb_mcs[0] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_sigb_mcs[1], ((float) mu_stats->nonmimo_sigb_mcs[1] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_sigb_mcs[2], ((float) mu_stats->nonmimo_sigb_mcs[2] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_sigb_mcs[3], ((float) mu_stats->nonmimo_sigb_mcs[3] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_sigb_mcs[4], ((float) mu_stats->nonmimo_sigb_mcs[4] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_sigb_mcs[5], ((float) mu_stats->nonmimo_sigb_mcs[5] / (float) mu_stats->nonmimo_rx) * 100);
|
||||||
|
ESP_LOGW(TAG, "(nonmimo)users, num1:%" PRIu32 "(%2.2f%%), num2:%" PRIu32 "(%2.2f%%), num3:%" PRIu32 "(%2.2f%%), num4:%" PRIu32 "(%2.2f%%), num5:%" PRIu32 "(%2.2f%%), num6:%" PRIu32 "(%2.2f%%), num7:%" PRIu32 "(%2.2f%%), num8:%" PRIu32 "(%2.2f%%), num9:%" PRIu32 "(%2.2f%%)",
|
||||||
|
mu_stats->nonmimo_user_num_occu[0], ((float) mu_stats->nonmimo_user_num_occu[0] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[1], ((float) mu_stats->nonmimo_user_num_occu[1] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[2], ((float) mu_stats->nonmimo_user_num_occu[2] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[3], ((float) mu_stats->nonmimo_user_num_occu[3] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[4], ((float) mu_stats->nonmimo_user_num_occu[4] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[5], ((float) mu_stats->nonmimo_user_num_occu[5] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[6], ((float) mu_stats->nonmimo_user_num_occu[6] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[7], ((float) mu_stats->nonmimo_user_num_occu[7] / (float) mu_stats->nonmimo_rx) * 100,
|
||||||
|
mu_stats->nonmimo_user_num_occu[8], ((float) mu_stats->nonmimo_user_num_occu[8] / (float) mu_stats->nonmimo_rx) * 100);
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
for (j = 0; j < 9; j++) {
|
||||||
|
if (!mu_stats->nonmimo_ru_alloc[i][j]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "(nonmimo)ru_allocation:0x%2x(%3" PRIu8 "), position:%" PRIu8 ", %5" PRIu32 "(%2.2f%%)", i, i, j + 1, mu_stats->nonmimo_ru_alloc[i][j],
|
||||||
|
((float) mu_stats->nonmimo_ru_alloc[i][j] / (float) mu_stats->nonmimo_rx) * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
||||||
|
if (!mu_stats->nonmimo[i].aid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mu_stats->aid != mu_stats->nonmimo[i].aid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tot_rx_nonmimo = mu_stats->nonmimo[i].occu_nsts[0] + mu_stats->nonmimo[i].occu_nsts[1] + mu_stats->nonmimo[i].occu_nsts[2] + mu_stats->nonmimo[i].occu_nsts[3];
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, txbf:%" PRIu32 ", dcm:%" PRIu32 "\n", i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||||
|
mu_stats->nonmimo[i].txbf, mu_stats->nonmimo[i].dcm);
|
||||||
|
printf("[%d]%said:0x%x, "
|
||||||
|
"mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), "
|
||||||
|
"mcs5:%" PRIu32 "(%2.2f%%), mcs6:%" PRIu32 "(%2.2f%%), mcs7:%" PRIu32 "(%2.2f%%), mcs8:%" PRIu32 "(%2.2f%%), mcs9:%" PRIu32 "(%2.2f%%), "
|
||||||
|
"mcs10:%" PRIu32 "(%2.2f%%), mcs11:%" PRIu32 "(%2.2f%%)\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[0], ((float) mu_stats->nonmimo[i].occu_mcs[0] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[1], ((float) mu_stats->nonmimo[i].occu_mcs[1] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[2], ((float) mu_stats->nonmimo[i].occu_mcs[2] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[3], ((float) mu_stats->nonmimo[i].occu_mcs[3] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[4], ((float) mu_stats->nonmimo[i].occu_mcs[4] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[5], ((float) mu_stats->nonmimo[i].occu_mcs[5] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[6], ((float) mu_stats->nonmimo[i].occu_mcs[6] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[7], ((float) mu_stats->nonmimo[i].occu_mcs[7] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[8], ((float) mu_stats->nonmimo[i].occu_mcs[8] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[9], ((float) mu_stats->nonmimo[i].occu_mcs[9] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[10], ((float) mu_stats->nonmimo[i].occu_mcs[10] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_mcs[11], ((float) mu_stats->nonmimo[i].occu_mcs[11] / (float) tot_rx_nonmimo) * 100);
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, "
|
||||||
|
"nsts0:%" PRIu32 "(%2.2f%%), nsts1:%" PRIu32 "(%2.2f%%), nsts2:%" PRIu32 "(%2.2f%%), nsts3:%" PRIu32 "(%2.2f%%)\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||||
|
mu_stats->nonmimo[i].occu_nsts[0], ((float) mu_stats->nonmimo[i].occu_nsts[0] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_nsts[1], ((float) mu_stats->nonmimo[i].occu_nsts[1] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_nsts[2], ((float) mu_stats->nonmimo[i].occu_nsts[2] / (float) tot_rx_nonmimo) * 100,
|
||||||
|
mu_stats->nonmimo[i].occu_nsts[3], ((float) mu_stats->nonmimo[i].occu_nsts[3] / (float) tot_rx_nonmimo) * 100);
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, "
|
||||||
|
"tot_rx_nonmimo:%8d, sta/dut:%2.2f%%\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->nonmimo[i].aid) ? "#" : " ", mu_stats->nonmimo[i].aid,
|
||||||
|
tot_rx_nonmimo, ((float) tot_rx_nonmimo / (float) mu_stats->nonmimo_rx) * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_rx_statistics_mimo(const esp_test_rx_mu_statistics_t *mu_stats)
|
||||||
|
{
|
||||||
|
if (!mu_stats->mimo_rx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int tot_rx_mimo = 0;
|
||||||
|
ESP_LOGW(TAG, "(mimo)dut rx:%" PRIu32 "", mu_stats->mimo_rx);
|
||||||
|
ESP_LOGW(TAG, "(mimo)sigb, mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), mcs5:%" PRIu32 "(%2.2f%%)",
|
||||||
|
mu_stats->mimo_sigb_mcs[0], ((float) mu_stats->mimo_sigb_mcs[0] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_sigb_mcs[1], ((float) mu_stats->mimo_sigb_mcs[1] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_sigb_mcs[2], ((float) mu_stats->mimo_sigb_mcs[2] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_sigb_mcs[3], ((float) mu_stats->mimo_sigb_mcs[3] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_sigb_mcs[4], ((float) mu_stats->mimo_sigb_mcs[4] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_sigb_mcs[5], ((float) mu_stats->mimo_sigb_mcs[5] / (float) mu_stats->mimo_rx) * 100);
|
||||||
|
ESP_LOGW(TAG, "(mimo)users num2:%" PRIu32 "(%2.2f%%), num3:%" PRIu32 "(%2.2f%%), num4:%" PRIu32 "(%2.2f%%), num5:%" PRIu32 "(%2.2f%%), num6:%" PRIu32 "(%2.2f%%), num7:%" PRIu32 "(%2.2f%%), num8:%" PRIu32 "(%2.2f%%)",
|
||||||
|
mu_stats->mimo_user_num_occu[0], ((float) mu_stats->mimo_user_num_occu[0] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[1], ((float) mu_stats->mimo_user_num_occu[1] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[2], ((float) mu_stats->mimo_user_num_occu[2] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[3], ((float) mu_stats->mimo_user_num_occu[3] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[4], ((float) mu_stats->mimo_user_num_occu[4] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[5], ((float) mu_stats->mimo_user_num_occu[5] / (float) mu_stats->mimo_rx) * 100,
|
||||||
|
mu_stats->mimo_user_num_occu[6], ((float) mu_stats->mimo_user_num_occu[6] / (float) mu_stats->mimo_rx) * 100);
|
||||||
|
for (i = 0; i < ESP_TEST_RX_MU_USER_NUM; i++) {
|
||||||
|
if (!mu_stats->mimo[i].aid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tot_rx_mimo = mu_stats->mimo[i].occu_ss[0] + mu_stats->mimo[i].occu_ss[1] + mu_stats->mimo[i].occu_ss[2] + mu_stats->mimo[i].occu_ss[3];
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, "
|
||||||
|
"mcs0:%" PRIu32 "(%2.2f%%), mcs1:%" PRIu32 "(%2.2f%%), mcs2:%" PRIu32 "(%2.2f%%), mcs3:%" PRIu32 "(%2.2f%%), mcs4:%" PRIu32 "(%2.2f%%), "
|
||||||
|
"mcs5:%" PRIu32 "(%2.2f%%), mcs6:%" PRIu32 "(%2.2f%%), mcs7:%" PRIu32 "(%2.2f%%), mcs8:%" PRIu32 "(%2.2f%%), mcs9:%" PRIu32 "(%2.2f%%), "
|
||||||
|
"mcs10:%" PRIu32 "(%2.2f%%), mcs11:%" PRIu32 "(%2.2f%%)\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||||
|
mu_stats->mimo[i].occu_mcs[0], ((float) mu_stats->mimo[i].occu_mcs[0] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[1], ((float) mu_stats->mimo[i].occu_mcs[1] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[2], ((float) mu_stats->mimo[i].occu_mcs[2] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[3], ((float) mu_stats->mimo[i].occu_mcs[3] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[4], ((float) mu_stats->mimo[i].occu_mcs[4] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[5], ((float) mu_stats->mimo[i].occu_mcs[5] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[6], ((float) mu_stats->mimo[i].occu_mcs[6] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[7], ((float) mu_stats->mimo[i].occu_mcs[7] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[8], ((float) mu_stats->mimo[i].occu_mcs[8] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[9], ((float) mu_stats->mimo[i].occu_mcs[9] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[10], ((float) mu_stats->mimo[i].occu_mcs[10] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_mcs[11], ((float) mu_stats->mimo[i].occu_mcs[11] / (float) tot_rx_mimo) * 100);
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, "
|
||||||
|
"ss0:%" PRIu32 "(%2.2f%%), ss1:%" PRIu32 "(%2.2f%%), ss2:%" PRIu32 "(%2.2f%%), ss3:%" PRIu32 "(%2.2f%%)\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||||
|
mu_stats->mimo[i].occu_ss[0], ((float) mu_stats->mimo[i].occu_ss[0] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_ss[1], ((float) mu_stats->mimo[i].occu_ss[1] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_ss[2], ((float) mu_stats->mimo[i].occu_ss[2] / (float) tot_rx_mimo) * 100,
|
||||||
|
mu_stats->mimo[i].occu_ss[3], ((float) mu_stats->mimo[i].occu_ss[3] / (float) tot_rx_mimo) * 100);
|
||||||
|
printf("[%" PRIu8 "]%said:0x%x, "
|
||||||
|
"tot_rx_mimo:%8d, sta/dut:%2.2f%%\n",
|
||||||
|
i, (mu_stats->aid == mu_stats->mimo[i].aid) ? "#" : " ", mu_stats->mimo[i].aid,
|
||||||
|
tot_rx_mimo, ((float) tot_rx_mimo / (float) mu_stats->mimo_rx) * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_hw_rx_statistics(void)
|
||||||
|
{
|
||||||
|
esp_test_hw_rx_statistics_t hw_rx_stats = { 0, };
|
||||||
|
esp_test_get_hw_rx_statistics(&hw_rx_stats);
|
||||||
|
printf(
|
||||||
|
"WDEVRX_FCS_ERR :%d\n"
|
||||||
|
"WDEVRX_ABORT :%d\n"
|
||||||
|
"WDEVRX_ABORT_FCS_PASS :%d\n"
|
||||||
|
"NRX_ERR_PWRDROP :%d\n"
|
||||||
|
"NRX_HESIGB_ERR :%d\n"
|
||||||
|
"WDEVRX_SAMEBM_ERRCNT :%d\n"
|
||||||
|
"WDEVRX_MPDU :%d\n"
|
||||||
|
"WDEVRX_END_CNT :%d\n"
|
||||||
|
"WDEVRX_DATASUC :%d\n"
|
||||||
|
"WDEVRX_LASTUNMATCH_ERR :%d\n"
|
||||||
|
"RXHUNG_STATIS :%d\n"
|
||||||
|
"TXHUNG_STATIS :%d\n"
|
||||||
|
"RXTXHUNG :%" PRIu32 "\n"
|
||||||
|
"WDEVRX_CFO :%d\n"
|
||||||
|
"WDEVRX_SF :%d\n"
|
||||||
|
"WDEVRX_OTHER_UCAST :%d\n"
|
||||||
|
"WDEVRX_BUF_FULLCNT :%d\n"
|
||||||
|
"WDEVRX_FIFO_OVFCNT :%d\n"
|
||||||
|
"WDEVRX_TKIP_ERRCNT :%d\n"
|
||||||
|
"WDEVRX_BTBLOCK_ERR :%d\n"
|
||||||
|
"WDEVRX_FREQHOP_ERR :%d\n"
|
||||||
|
"WDEVRX_ACK_INT_CNT :%d\n"
|
||||||
|
"WDEVRX_RTS_INT_CNT :%d\n"
|
||||||
|
"BRX_ERR_AGC :%d\n"
|
||||||
|
"BRX_ERR :%d\n"
|
||||||
|
"NRX_ERR :%d\n"
|
||||||
|
"NRX_ERR_ABORT :%d\n"
|
||||||
|
"NRX_ERR_AGCEXIT :%d\n"
|
||||||
|
"NRX_ERR_BBOFF :%d\n"
|
||||||
|
"NRX_ERR_FDM_WDG :%d\n"
|
||||||
|
"NRX_ERR_RESTART :%d\n"
|
||||||
|
"NRX_ERR_SERV :%d\n"
|
||||||
|
"NRX_ERR_TXOVER :%d\n"
|
||||||
|
"NRX_HE_UNSUPPORT :%d\n"
|
||||||
|
"NRX_HTSIG_ERR :%d\n"
|
||||||
|
"NRX_HEUNSUPPORT :%d\n"
|
||||||
|
"NRX_HESIGA_CRC :%d\n",
|
||||||
|
hw_rx_stats.rx_fcs_err,
|
||||||
|
hw_rx_stats.rx_abort,
|
||||||
|
hw_rx_stats.rx_abort_fcs_pass,
|
||||||
|
hw_rx_stats.nrx_err_pwrdrop,
|
||||||
|
hw_rx_stats.nrx_hesigb_err,
|
||||||
|
hw_rx_stats.rx_samebm_errcnt,
|
||||||
|
hw_rx_stats.rx_mpdu,
|
||||||
|
hw_rx_stats.rx_end_cnt,
|
||||||
|
hw_rx_stats.rx_datasuc,
|
||||||
|
hw_rx_stats.rx_lastunmatch_err,
|
||||||
|
hw_rx_stats.rxhung_statis,
|
||||||
|
hw_rx_stats.txhung_statis,
|
||||||
|
hw_rx_stats.rxtxhung,
|
||||||
|
hw_rx_stats.rx_cfo_hz,
|
||||||
|
hw_rx_stats.rx_sf,
|
||||||
|
hw_rx_stats.rx_other_ucast,
|
||||||
|
hw_rx_stats.rx_buf_fullcnt,
|
||||||
|
hw_rx_stats.rx_fifo_ovfcnt,
|
||||||
|
hw_rx_stats.rx_tkip_errcnt,
|
||||||
|
hw_rx_stats.rx_btblock_err,
|
||||||
|
hw_rx_stats.rx_freqhop_err,
|
||||||
|
hw_rx_stats.rx_ack_int_cnt,
|
||||||
|
hw_rx_stats.rx_rts_int_cnt,
|
||||||
|
hw_rx_stats.brx_err_agc,
|
||||||
|
hw_rx_stats.brx_err,
|
||||||
|
hw_rx_stats.nrx_err,
|
||||||
|
hw_rx_stats.nrx_err_abort,
|
||||||
|
hw_rx_stats.nrx_err_agcexit,
|
||||||
|
hw_rx_stats.nrx_err_bboff,
|
||||||
|
hw_rx_stats.nrx_err_fdm_wdg,
|
||||||
|
hw_rx_stats.nrx_err_restart,
|
||||||
|
hw_rx_stats.nrx_err_serv,
|
||||||
|
hw_rx_stats.nrx_err_txover,
|
||||||
|
hw_rx_stats.nrx_err_unsupport,
|
||||||
|
hw_rx_stats.nrx_htsig_err,
|
||||||
|
hw_rx_stats.nrx_heunsupport,
|
||||||
|
hw_rx_stats.nrx_hesiga_crc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wifi_cmd_clr_rx_statistics(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Clear rx statistics");
|
||||||
|
esp_wifi_clr_rx_statistics(0);
|
||||||
|
esp_wifi_clr_rx_statistics(7);
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||||
|
esp_test_clr_rx_error_occurs();
|
||||||
|
esp_wifi_clr_rx_mu_statistics();
|
||||||
|
#endif
|
||||||
|
esp_test_clr_hw_statistics();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_rx_mu_statistics(void)
|
||||||
|
{
|
||||||
|
/* mu */
|
||||||
|
esp_wifi_get_rx_mu_statistics(&rx_mu_stats);
|
||||||
|
/* MIMO */
|
||||||
|
print_rx_statistics_mimo(&rx_mu_stats);
|
||||||
|
/* non-MIMO */
|
||||||
|
print_rx_statistics_nonmimo(&rx_mu_stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wifi_cmd_get_rx_statistics(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Get rx statistics");
|
||||||
|
esp_test_rx_statistics_t rx_stats = { 0, };
|
||||||
|
esp_test_rx_error_occurs_t rx_error_occurs = { 0, };
|
||||||
|
|
||||||
|
esp_wifi_get_rx_statistics(0, &rx_stats); //tid=0
|
||||||
|
print_hw_tb_statistics();
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "(0)legacy:%" PRIu32 ", ht(ht:%" PRIu32 ", ht_retry:%" PRIu32 "/%2.2f%%, ht_noeb:%" PRIu32 "/%2.2f%%)",
|
||||||
|
rx_stats.legacy,
|
||||||
|
rx_stats.ht, rx_stats.ht_retry,
|
||||||
|
rx_stats.ht_retry ? ((float) ((float) rx_stats.ht_retry / (float) rx_stats.ht) * 100) : 0,
|
||||||
|
rx_stats.ht_noeb, rx_stats.ht_noeb ? ((float) ((float) rx_stats.ht_noeb / (float) rx_stats.ht) * 100) : 0);
|
||||||
|
ESP_LOGW(TAG, "(0)su(su:%" PRIu32 ", su_txbf:%" PRIu32 ", su_stbc:%" PRIu32 ", su_retry:%" PRIu32 "/%2.2f%%, ersu:%" PRIu32 ", ersu_dcm:%" PRIu32 ", su_noeb:%" PRIu32 "/%2.2f%%)",
|
||||||
|
rx_stats.su,
|
||||||
|
rx_stats.su_txbf, rx_stats.su_stbc,
|
||||||
|
rx_stats.su_retry,
|
||||||
|
rx_stats.su_retry ? ((float) ((float) rx_stats.su_retry / (float) rx_stats.su) * 100) : 0,
|
||||||
|
rx_stats.ersu,
|
||||||
|
rx_stats.ersu_dcm,
|
||||||
|
rx_stats.su_noeb, rx_stats.su_noeb ? ((float) ((float) rx_stats.su_noeb / (float) rx_stats.su) * 100) : 0);
|
||||||
|
ESP_LOGW(TAG, "(0)mu(mu:%" PRIu32 ", mimo:%" PRIu32 ", non-mimo:%" PRIu32 ", txbf:%" PRIu32 ", stbc:%" PRIu32 ", mu_retry:%" PRIu32 "/%2.2f%%, mu_noeb:%" PRIu32 "/%2.2f%%)",
|
||||||
|
rx_stats.mu,
|
||||||
|
rx_stats.mu_mimo,
|
||||||
|
rx_stats.mu_ofdma, rx_stats.mu_txbf, rx_stats.mu_stbc,
|
||||||
|
rx_stats.mu_retry,
|
||||||
|
rx_stats.mu_retry ? ((float) ((float) rx_stats.mu_retry / (float) rx_stats.mu) * 100) : 0,
|
||||||
|
rx_stats.mu_noeb, rx_stats.mu_noeb ? ((float) ((float) rx_stats.mu_noeb / (float) rx_stats.mu) * 100) : 0);
|
||||||
|
|
||||||
|
memset(&rx_stats, 0, sizeof(rx_stats));
|
||||||
|
esp_wifi_get_rx_statistics(7, &rx_stats); //tid=7
|
||||||
|
ESP_LOGW(TAG, "(7)legacy:%" PRIu32 ", ht:%" PRIu32 ", su:%" PRIu32 ", su_txbf:%" PRIu32 ", ersu:%" PRIu32 ", mu:%" PRIu32, rx_stats.legacy,
|
||||||
|
rx_stats.ht, rx_stats.su, rx_stats.su_txbf, rx_stats.ersu, rx_stats.mu);
|
||||||
|
ESP_LOGW(TAG, "(hw)isr:%" PRIu32 ", nblks:%" PRIu32, rx_stats.rx_isr, rx_stats.rx_nblks);
|
||||||
|
/* hw rx statistics */
|
||||||
|
print_hw_rx_statistics();
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_MU_STATS
|
||||||
|
print_rx_mu_statistics();
|
||||||
|
#endif
|
||||||
|
esp_test_get_rx_error_occurs(&rx_error_occurs);
|
||||||
|
ESP_LOGW(TAG, "(rx)tot_errors:%" PRIu32, rx_error_occurs.tot);
|
||||||
|
int known_errors = 0; //rx error: 0x40-0xff
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
if (rx_error_occurs.occurs[i]) {
|
||||||
|
known_errors += rx_error_occurs.occurs[i];
|
||||||
|
printf("[%3d] 0x%x, %8" PRIu32 ", %2.2f%%\n", i, (i ? 0xf5 : 0xc6), rx_error_occurs.occurs[i], ((float) rx_error_occurs.occurs[i] / (float) rx_error_occurs.tot) * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rx_error_occurs.tot - known_errors) {
|
||||||
|
printf("[%3d]others, %8" PRIu32 ", %2.2f%%\n\n", i, rx_error_occurs.tot - known_errors, ((float) known_errors / (float) rx_error_occurs.tot) * 100);
|
||||||
|
}
|
||||||
|
wifi_cmd_clr_rx_statistics(0, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS || CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS */
|
||||||
|
|
||||||
|
void register_wifi_stats(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
|
||||||
|
/* get tx statistics */
|
||||||
|
const esp_console_cmd_t tx_stats_cmd = {
|
||||||
|
.command = "tx",
|
||||||
|
.help = "get tx statistics",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_get_tx_statistics,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&tx_stats_cmd));
|
||||||
|
/* clear tx statistics */
|
||||||
|
const esp_console_cmd_t clr_cmd = {
|
||||||
|
.command = "clrtx",
|
||||||
|
.help = "clear tx statistics",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_clr_tx_statistics,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_cmd));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
|
||||||
|
/* get rx statistics */
|
||||||
|
const esp_console_cmd_t rx_stats_cmd = {
|
||||||
|
.command = "rx",
|
||||||
|
.help = "get rx statistics",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_get_rx_statistics,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&rx_stats_cmd));
|
||||||
|
/* clear rx statistics */
|
||||||
|
const esp_console_cmd_t clr_rx_cmd = {
|
||||||
|
.command = "clrrx",
|
||||||
|
.help = "clear rx statistics",
|
||||||
|
.hint = NULL,
|
||||||
|
.func = &wifi_cmd_clr_rx_statistics,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_console_cmd_register(&clr_rx_cmd));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
CONFIG_IDF_TARGET="esp32p4"
|
||||||
|
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
|
CONFIG_EXAMPLE_ENABLE_STATIC_IP=n
|
||||||
|
CONFIG_PM_ENABLE=y
|
||||||
|
CONFIG_PM_SLP_DISABLE_GPIO=y
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||||
|
CONFIG_LWIP_ESP_GRATUITOUS_ARP=n
|
||||||
|
CONFIG_SLAVE_IDF_TARGET_ESP32C5=y
|
||||||
|
CONFIG_EXAMPLE_MAX_CPU_FREQ_90=y
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
|
# Add the wrap flag for esp_wifi_init
|
||||||
|
add_compile_options(-Wl,--wrap=esp_wifi_init)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
list(APPEND EXCLUDE_COMPONENTS lwip esp_netif)
|
||||||
|
|
||||||
|
set(COMPONENTS esp_timer esptool_py bootloader main nvs_flash esp_rom esp_wifi protocomm driver mqtt wpa_supplicant wifi_provisioning esp_driver_sdio)
|
||||||
|
|
||||||
|
#list(APPEND COMPONENTS esp_gdbstub) # incase gdbstub needed
|
||||||
|
project(network_adapter)
|
||||||
|
idf_build_set_property(COMPILE_OPTIONS "-fdiagnostics-color=always" APPEND)
|
||||||
|
|
||||||
|
# for disable 80211 sanity check
|
||||||
|
add_link_options("-Wl,-z,muldefs")
|
||||||
|
|
||||||
|
if(EXISTS "${PROJECT_DIR}/../common")
|
||||||
|
set(common_dir "${PROJECT_DIR}/../common")
|
||||||
|
message(STATUS "common: ${common_dir}")
|
||||||
|
elseif(EXISTS "${PROJECT_DIR}/main/common")
|
||||||
|
set(common_dir "${PROJECT_DIR}/main/common")
|
||||||
|
message(STATUS "common: ${common_dir}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not find 'common' directory in either '${PROJECT_DIR}/../common' or '${PROJECT_DIR}/main/common'")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(EXISTS "${common_dir}/esp_hosted_lwip_src_port_hook.h")
|
||||||
|
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 "${common_dir}")
|
||||||
|
target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"${common_dir}/esp_hosted_lwip_src_port_hook.h\"")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
### read and display FW Version
|
||||||
|
file(READ "${CMAKE_CURRENT_LIST_DIR}/main/esp_hosted_coprocessor_fw_ver.h" HEADER_CONTENTS)
|
||||||
|
set(PROJECT_VERSION_REGEX "#define[ \t]+PROJECT_VERSION_MAJOR_1[ \t]+([0-9]+)[ \t\n]+#define[ \t]+PROJECT_VERSION_MINOR_1[ \t]+([0-9]+)[ \t\n]+#define[ \t]+PROJECT_VERSION_PATCH_1[ \t]+([0-9]+)")
|
||||||
|
string(REGEX MATCH "${PROJECT_VERSION_REGEX}" PROJECT_VERSION_MATCH "${HEADER_CONTENTS}")
|
||||||
|
|
||||||
|
if(PROJECT_VERSION_MATCH)
|
||||||
|
set(PROJECT_VERSION_MAJOR_1 "${CMAKE_MATCH_1}")
|
||||||
|
set(PROJECT_VERSION_MINOR_1 "${CMAKE_MATCH_2}")
|
||||||
|
set(PROJECT_VERSION_PATCH_1 "${CMAKE_MATCH_3}")
|
||||||
|
|
||||||
|
# Construct project version
|
||||||
|
set(PROJECT_VER "${PROJECT_VERSION_MAJOR_1}.${PROJECT_VERSION_MINOR_1}.${PROJECT_VERSION_PATCH_1}")
|
||||||
|
|
||||||
|
message(*************************************************************************************)
|
||||||
|
message(" Building ESP-Hosted-MCU FW :: ${PROJECT_VER} ")
|
||||||
|
message(*************************************************************************************)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Failed to read project version from main/esp_hosted_coprocessor_fw_ver.h")
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/common")
|
||||||
|
set(common_dir "${CMAKE_CURRENT_SOURCE_DIR}/common")
|
||||||
|
else()
|
||||||
|
set(common_dir "../../common")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(COMPONENT_SRCS
|
||||||
|
"slave_control.c"
|
||||||
|
"${common_dir}/proto/esp_hosted_rpc.pb-c.c"
|
||||||
|
"${common_dir}/utils/esp_hosted_cli.c"
|
||||||
|
"protocomm_pserial.c"
|
||||||
|
"esp_hosted_coprocessor.c"
|
||||||
|
"slave_bt.c"
|
||||||
|
"mempool.c"
|
||||||
|
"stats.c"
|
||||||
|
"mempool_ll.c"
|
||||||
|
"host_power_save.c"
|
||||||
|
"lwip_filter.c"
|
||||||
|
"disable_ieee80211_raw_frame_sanity_check.c"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS
|
||||||
|
"."
|
||||||
|
"${common_dir}"
|
||||||
|
"${common_dir}/log"
|
||||||
|
"${common_dir}/proto"
|
||||||
|
"${common_dir}/rpc"
|
||||||
|
"${common_dir}/transport"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Select BT UART code based on IDF Target
|
||||||
|
if(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
list(APPEND COMPONENT_SRCS slave_bt_uart_esp32.c)
|
||||||
|
elseif(CONFIG_IDF_TARGET_ESP32C3 OR CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
list(APPEND COMPONENT_SRCS slave_bt_uart_esp32c3_s3.c)
|
||||||
|
else()
|
||||||
|
list(APPEND COMPONENT_SRCS slave_bt_uart_esp32xx.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_ESP_SDIO_HOST_INTERFACE)
|
||||||
|
list(APPEND COMPONENT_SRCS sdio_slave_api.c)
|
||||||
|
elseif(CONFIG_ESP_SPI_HOST_INTERFACE)
|
||||||
|
list(APPEND COMPONENT_SRCS spi_slave_api.c)
|
||||||
|
elseif(CONFIG_ESP_SPI_HD_MODE)
|
||||||
|
list(APPEND COMPONENT_SRCS spi_hd_slave_api.c)
|
||||||
|
else(CONFIG_ESP_UART_HOST_INTERFACE)
|
||||||
|
list(APPEND COMPONENT_SRCS uart_slave_api.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_ESP_HOSTED_COPROCESSOR_EXAMPLE_MQTT)
|
||||||
|
list(APPEND COMPONENT_SRCS mqtt_example.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_ESP_HOSTED_COPROCESSOR_EXAMPLE_HTTP_CLIENT)
|
||||||
|
list(APPEND COMPONENT_SRCS http_req.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# cli
|
||||||
|
list(APPEND COMPONENT_ADD_INCLUDEDIRS "${common_dir}/utils")
|
||||||
|
list(APPEND COMPONENT_SRCS "${common_dir}/utils/esp_hosted_cli.c")
|
||||||
|
|
||||||
|
|
||||||
|
register_component()
|
||||||
|
|
||||||
|
# Add directory of protocomm_priv.h to include paths
|
||||||
|
idf_component_get_property(protocomm_dir protocomm COMPONENT_DIR)
|
||||||
|
target_include_directories(${COMPONENT_LIB} PRIVATE "${protocomm_dir}/src/common")
|
||||||
|
|
||||||
|
# Add linker options to wrap esp_wifi_init function
|
||||||
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_wifi_init")
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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__ */
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
@@ -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}"
|
||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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
@@ -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>
|
||||||
@@ -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.
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
[](https://github.com/protobuf-c/protobuf-c/actions) [](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.
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
exec autoreconf -fvi
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
!CMakeLists.txt
|
||||||
+218
@@ -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)
|
||||||
@@ -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}
|
||||||
|
])
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
libtool.m4
|
||||||
|
ltoptions.m4
|
||||||
|
ltsugar.m4
|
||||||
|
ltversion.m4
|
||||||
|
lt~obsolete.m4
|
||||||
+74
@@ -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
|
||||||
+948
@@ -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
|
||||||
|
|
||||||
|
]])
|
||||||
@@ -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 module’s 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])])
|
||||||
|
])
|
||||||
+53
@@ -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")
|
||||||
|
])
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
|
])
|
||||||
+13
@@ -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}
|
||||||
+28
@@ -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;
|
||||||
+3672
File diff suppressed because it is too large
Load Diff
+1110
File diff suppressed because it is too large
Load Diff
+86
@@ -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;
|
||||||
|
}
|
||||||
+163
@@ -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
|
||||||
+100
@@ -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__
|
||||||
@@ -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
|
||||||
@@ -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__
|
||||||
+149
@@ -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
|
||||||
+98
@@ -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__
|
||||||
+90
@@ -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
|
||||||
+110
@@ -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__
|
||||||
@@ -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
|
||||||
@@ -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__
|
||||||
@@ -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
|
||||||
@@ -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__
|
||||||
+176
@@ -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
|
||||||
+106
@@ -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__
|
||||||
+558
@@ -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
|
||||||
@@ -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__
|
||||||
+633
@@ -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
|
||||||
@@ -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__
|
||||||
+129
@@ -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
|
||||||
+97
@@ -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__
|
||||||
+211
@@ -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
|
||||||
+96
@@ -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__
|
||||||
+294
@@ -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
|
||||||
@@ -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__
|
||||||
+160
@@ -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
|
||||||
+100
@@ -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__
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
+71
@@ -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] = ☎
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
+62
@@ -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" };
|
||||||
+1169
File diff suppressed because it is too large
Load Diff
+2383
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
|||||||
|
issue204
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+15
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
issue220
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+20
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
issue251
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+11
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
issue330
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
message pbr_route {
|
||||||
|
repeated int32 acl_id = 10;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
issue375
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user