diff --git a/configure b/configure index bfd9d79..64c7bdc 100755 --- a/configure +++ b/configure @@ -60046,7 +60046,7 @@ shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib /lib64 /usr/lib64" +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib64 /lib64 /usr/lib64" need_lib_prefix=unknown hardcode_into_libs=no @@ -64013,7 +64013,7 @@ shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/lib64" need_lib_prefix=unknown hardcode_into_libs=no diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c deleted file mode 100644 index 245ea64..0000000 --- a/lib/minitasn1/coding.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - - -/*****************************************************/ -/* File: coding.c */ -/* Description: Functions to create a DER coding of */ -/* an ASN1 type. */ -/*****************************************************/ - -#include -#include "parser_aux.h" -#include -#include "element.h" -#include "minmax.h" -#include - -#define MAX_TAG_LEN 16 - -/******************************************************/ -/* Function : _asn1_error_description_value_not_found */ -/* Description: creates the ErrorDescription string */ -/* for the ASN1_VALUE_NOT_FOUND error. */ -/* Parameters: */ -/* node: node of the tree where the value is NULL. */ -/* ErrorDescription: string returned. */ -/* Return: */ -/******************************************************/ -static void -_asn1_error_description_value_not_found (asn1_node node, - char *ErrorDescription) -{ - - if (ErrorDescription == NULL) - return; - - Estrcpy (ErrorDescription, ":: value of element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "' not found"); - -} - -/** - * asn1_length_der: - * @len: value to convert. - * @der: buffer to hold the returned encoding (may be %NULL). - * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]). - * - * Creates the DER encoding of the provided length value. - * The @der buffer must have enough room for the output. The maximum - * length this function will encode is %ASN1_MAX_LENGTH_SIZE. - * - * To know the size of the DER encoding use a %NULL value for @der. - **/ -void -asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) -{ - int k; - unsigned char temp[ASN1_MAX_LENGTH_SIZE]; -#if SIZEOF_UNSIGNED_LONG_INT > 8 - len &= 0xFFFFFFFFFFFFFFFF; -#endif - - if (len < 128) - { - /* short form */ - if (der != NULL) - der[0] = (unsigned char) len; - *der_len = 1; - } - else - { - /* Long form */ - k = 0; - while (len) - { - temp[k++] = len & 0xFF; - len = len >> 8; - } - *der_len = k + 1; - if (der != NULL) - { - der[0] = ((unsigned char) k & 0x7F) + 128; - while (k--) - der[*der_len - 1 - k] = temp[k]; - } - } -} - -/******************************************************/ -/* Function : _asn1_tag_der */ -/* Description: creates the DER coding for the CLASS */ -/* and TAG parameters. */ -/* It is limited by the ASN1_MAX_TAG_SIZE variable */ -/* Parameters: */ -/* class: value to convert. */ -/* tag_value: value to convert. */ -/* ans: string returned. */ -/* ans_len: number of meaningful bytes of ANS */ -/* (ans[0]..ans[ans_len-1]). */ -/* Return: */ -/******************************************************/ -static void -_asn1_tag_der (unsigned char class, unsigned int tag_value, - unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len) -{ - int k; - unsigned char temp[ASN1_MAX_TAG_SIZE]; - - if (tag_value < 31) - { - /* short form */ - ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); - *ans_len = 1; - } - else - { - /* Long form */ - ans[0] = (class & 0xE0) + 31; - k = 0; - while (tag_value != 0) - { - temp[k++] = tag_value & 0x7F; - tag_value >>= 7; - - if (k > ASN1_MAX_TAG_SIZE - 1) - break; /* will not encode larger tags */ - } - *ans_len = k + 1; - while (k--) - ans[*ans_len - 1 - k] = temp[k] + 128; - ans[*ans_len - 1] -= 128; - } -} - -/** - * asn1_octet_der: - * @str: the input data. - * @str_len: STR length (str[0]..str[*str_len-1]). - * @der: encoded string returned. - * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]). - * - * Creates a length-value DER encoding for the input data. - * The DER encoding of the input data will be placed in the @der variable. - * - * Note that the OCTET STRING tag is not included in the output. - * - * This function does not return any value because it is expected - * that @der_len will contain enough bytes to store the string - * plus the DER encoding. The DER encoding size can be obtained using - * asn1_length_der(). - **/ -void -asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len) -{ - int len_len; - - if (der == NULL || str_len < 0) - return; - - asn1_length_der (str_len, der, &len_len); - memcpy (der + len_len, str, str_len); - *der_len = str_len + len_len; -} - - -/** - * asn1_encode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @str: the string data. - * @str_len: the string length - * @tl: the encoded tag and length - * @tl_len: the bytes of the @tl field - * - * Creates the DER encoding for various simple ASN.1 types like strings etc. - * It stores the tag and length in @tl, which should have space for at least - * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl. - * - * The complete DER encoding should consist of the value in @tl appended - * with the provided @str. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - unsigned int str_len, unsigned char *tl, - unsigned int *tl_len) -{ - int tag_len, len_len; - unsigned tlen; - unsigned char der_tag[ASN1_MAX_TAG_SIZE]; - unsigned char der_length[ASN1_MAX_LENGTH_SIZE]; - unsigned char *p; - - if (str == NULL) - return ASN1_VALUE_NOT_VALID; - - if (ETYPE_OK (etype) == 0) - return ASN1_VALUE_NOT_VALID; - - /* doesn't handle constructed classes */ - if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL) - return ASN1_VALUE_NOT_VALID; - - _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len); - - asn1_length_der (str_len, der_length, &len_len); - - if (tag_len <= 0 || len_len <= 0) - return ASN1_VALUE_NOT_VALID; - - tlen = tag_len + len_len; - - if (*tl_len < tlen) - return ASN1_MEM_ERROR; - - p = tl; - memcpy (p, der_tag, tag_len); - p += tag_len; - memcpy (p, der_length, len_len); - - *tl_len = tlen; - - return ASN1_SUCCESS; -} - -/******************************************************/ -/* Function : _asn1_time_der */ -/* Description: creates the DER coding for a TIME */ -/* type (length included). */ -/* Parameters: */ -/* str: TIME null-terminated string. */ -/* der: string returned. */ -/* der_len: number of meaningful bytes of DER */ -/* (der[0]..der[ans_len-1]). Initially it */ -/* if must store the lenght of DER. */ -/* Return: */ -/* ASN1_MEM_ERROR when DER isn't big enough */ -/* ASN1_SUCCESS otherwise */ -/******************************************************/ -static int -_asn1_time_der (unsigned char *str, int str_len, unsigned char *der, - int *der_len) -{ - int len_len; - int max_len; - - if (der == NULL) - return ASN1_VALUE_NOT_VALID; - - max_len = *der_len; - - asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); - - if ((len_len + str_len) <= max_len) - memcpy (der + len_len, str, str_len); - *der_len = len_len + str_len; - - if ((*der_len) > max_len) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - - -/* -void -_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) -{ - int len_len,str_len; - char temp[20]; - - if(str==NULL) return; - str_len=asn1_get_length_der(der,*der_len,&len_len); - if (str_len<0) return; - memcpy(temp,der+len_len,str_len); - *der_len=str_len+len_len; - switch(str_len) - { - case 11: - temp[10]=0; - strcat(temp,"00+0000"); - break; - case 13: - temp[12]=0; - strcat(temp,"+0000"); - break; - case 15: - temp[15]=0; - memmove(temp+12,temp+10,6); - temp[10]=temp[11]='0'; - break; - case 17: - temp[17]=0; - break; - default: - return; - } - strcpy(str,temp); -} -*/ - -static -void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len) -{ - int first, k; - unsigned char bit7; - - first = 0; - for (k = sizeof(val); k >= 0; k--) - { - bit7 = (val >> (k * 7)) & 0x7F; - if (bit7 || first || !k) - { - if (k) - bit7 |= 0x80; - if (max_len > (*der_len)) - der[*der_len] = bit7; - (*der_len)++; - first = 1; - } - } -} - -/******************************************************/ -/* Function : _asn1_object_id_der */ -/* Description: creates the DER coding for an */ -/* OBJECT IDENTIFIER type (length included). */ -/* Parameters: */ -/* str: OBJECT IDENTIFIER null-terminated string. */ -/* der: string returned. */ -/* der_len: number of meaningful bytes of DER */ -/* (der[0]..der[ans_len-1]). Initially it */ -/* must store the length of DER. */ -/* Return: */ -/* ASN1_MEM_ERROR when DER isn't big enough */ -/* ASN1_SUCCESS if succesful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_object_id_der (const char *str, unsigned char *der, int *der_len) -{ - int len_len, counter, max_len; - char *temp, *n_end, *n_start; - uint64_t val, val1 = 0; - int str_len = _asn1_strlen (str); - - max_len = *der_len; - *der_len = 0; - - if (der == NULL && max_len > 0) - return ASN1_VALUE_NOT_VALID; - - temp = malloc (str_len + 2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - memcpy (temp, str, str_len); - temp[str_len] = '.'; - temp[str_len + 1] = 0; - - counter = 0; - n_start = temp; - while ((n_end = strchr (n_start, '.'))) - { - *n_end = 0; - val = _asn1_strtou64 (n_start, NULL, 10); - counter++; - - if (counter == 1) - { - val1 = val; - } - else if (counter == 2) - { - uint64_t val0; - - if (val1 > 2) - { - free(temp); - return ASN1_VALUE_NOT_VALID; - } - else if ((val1 == 0 || val1 == 1) && val > 39) - { - free(temp); - return ASN1_VALUE_NOT_VALID; - } - - val0 = 40 * val1 + val; - encode_val(val0, der, max_len, der_len); - } - else - { - encode_val(val, der, max_len, der_len); - } - n_start = n_end + 1; - } - - asn1_length_der (*der_len, NULL, &len_len); - if (max_len >= (*der_len + len_len)) - { - memmove (der + len_len, der, *der_len); - asn1_length_der (*der_len, der, &len_len); - } - *der_len += len_len; - - free (temp); - - if (max_len < (*der_len)) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -/** - * asn1_object_id_der: - * @str: An object identifier in numeric, dot format. - * @der: buffer to hold the returned encoding (may be %NULL). - * @der_len: initially the size of @der; will hold the final size. - * @flags: must be zero - * - * Creates the DER encoding of the provided object identifier. - * - * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID - * if @str is not a valid OID, %ASN1_MEM_ERROR if the @der - * vector isn't big enough and in this case @der_len will contain the - * length needed. - **/ -int asn1_object_id_der(const char *str, unsigned char *der, int *der_len, unsigned flags) -{ - unsigned char tag_der[MAX_TAG_LEN]; - int tag_len = 0, r; - int max_len = *der_len; - - *der_len = 0; - - _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), - tag_der, &tag_len); - - if (max_len > tag_len) - { - memcpy(der, tag_der, tag_len); - } - max_len -= tag_len; - der += tag_len; - - r = _asn1_object_id_der (str, der, &max_len); - if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS) - { - *der_len = max_len + tag_len; - } - - return r; -} - -static const unsigned char bit_mask[] = - { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; - -/** - * asn1_bit_der: - * @str: BIT string. - * @bit_len: number of meaningful bits in STR. - * @der: string returned. - * @der_len: number of meaningful bytes of DER - * (der[0]..der[ans_len-1]). - * - * Creates a length-value DER encoding for the input data - * as it would have been for a BIT STRING. - * The DER encoded data will be copied in @der. - * - * Note that the BIT STRING tag is not included in the output. - * - * This function does not return any value because it is expected - * that @der_len will contain enough bytes to store the string - * plus the DER encoding. The DER encoding size can be obtained using - * asn1_length_der(). - **/ -void -asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len) -{ - int len_len, len_byte, len_pad; - - if (der == NULL) - return; - - len_byte = bit_len >> 3; - len_pad = 8 - (bit_len & 7); - if (len_pad == 8) - len_pad = 0; - else - len_byte++; - asn1_length_der (len_byte + 1, der, &len_len); - der[len_len] = len_pad; - - if (str) - memcpy (der + len_len + 1, str, len_byte); - der[len_len + len_byte] &= bit_mask[len_pad]; - *der_len = len_byte + len_len + 1; -} - - -/******************************************************/ -/* Function : _asn1_complete_explicit_tag */ -/* Description: add the length coding to the EXPLICIT */ -/* tags. */ -/* Parameters: */ -/* node: pointer to the tree element. */ -/* der: string with the DER coding of the whole tree*/ -/* counter: number of meaningful bytes of DER */ -/* (der[0]..der[*counter-1]). */ -/* max_len: size of der vector */ -/* Return: */ -/* ASN1_MEM_ERROR if der vector isn't big enough, */ -/* otherwise ASN1_SUCCESS. */ -/******************************************************/ -static int -_asn1_complete_explicit_tag (asn1_node node, unsigned char *der, - int *counter, int *max_len) -{ - asn1_node p; - int is_tag_implicit, len2, len3; - unsigned char temp[SIZEOF_UNSIGNED_INT]; - - if (der == NULL && *max_len > 0) - return ASN1_VALUE_NOT_VALID; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - if (p == NULL) - return ASN1_DER_ERROR; - /* When there are nested tags we must complete them reverse to - the order they were created. This is because completing a tag - modifies all data within it, including the incomplete tags - which store buffer positions -- simon@josefsson.org 2002-09-06 - */ - while (p->right) - p = p->right; - while (p && p != node->down->left) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_EXPLICIT) - { - len2 = strtol (p->name, NULL, 10); - _asn1_set_name (p, NULL); - - asn1_length_der (*counter - len2, temp, &len3); - if (len3 <= (*max_len)) - { - memmove (der + len2 + len3, der + len2, - *counter - len2); - memcpy (der + len2, temp, len3); - } - *max_len -= len3; - *counter += len3; - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - is_tag_implicit = 1; - } - } - } - p = p->left; - } - } - - if (*max_len < 0) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -const tag_and_class_st _asn1_tags[] = { - [ASN1_ETYPE_GENERALSTRING] = - {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"}, - [ASN1_ETYPE_NUMERIC_STRING] = - {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"}, - [ASN1_ETYPE_IA5_STRING] = - {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"}, - [ASN1_ETYPE_TELETEX_STRING] = - {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"}, - [ASN1_ETYPE_PRINTABLE_STRING] = - {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"}, - [ASN1_ETYPE_UNIVERSAL_STRING] = - {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"}, - [ASN1_ETYPE_BMP_STRING] = - {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"}, - [ASN1_ETYPE_UTF8_STRING] = - {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"}, - [ASN1_ETYPE_VISIBLE_STRING] = - {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"}, - [ASN1_ETYPE_OCTET_STRING] = - {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"}, - [ASN1_ETYPE_BIT_STRING] = - {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"}, - [ASN1_ETYPE_OBJECT_ID] = - {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"}, - [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"}, - [ASN1_ETYPE_BOOLEAN] = - {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"}, - [ASN1_ETYPE_INTEGER] = - {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"}, - [ASN1_ETYPE_ENUMERATED] = - {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"}, - [ASN1_ETYPE_SEQUENCE] = - {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SEQUENCE"}, - [ASN1_ETYPE_SEQUENCE_OF] = - {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SEQ_OF"}, - [ASN1_ETYPE_SET] = - {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"}, - [ASN1_ETYPE_SET_OF] = - {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, - "type:SET_OF"}, - [ASN1_ETYPE_GENERALIZED_TIME] = - {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"}, - [ASN1_ETYPE_UTC_TIME] = - {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"}, -}; - -unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); - -/******************************************************/ -/* Function : _asn1_insert_tag_der */ -/* Description: creates the DER coding of tags of one */ -/* NODE. */ -/* Parameters: */ -/* node: pointer to the tree element. */ -/* der: string returned */ -/* counter: number of meaningful bytes of DER */ -/* (counter[0]..der[*counter-1]). */ -/* max_len: size of der vector */ -/* Return: */ -/* ASN1_GENERIC_ERROR if the type is unknown, */ -/* ASN1_MEM_ERROR if der vector isn't big enough, */ -/* otherwise ASN1_SUCCESS. */ -/******************************************************/ -static int -_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, - int *max_len) -{ - asn1_node p; - int tag_len, is_tag_implicit; - unsigned char class, class_implicit = 0, temp[MAX(SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; - unsigned long tag_implicit = 0; - unsigned char tag_der[MAX_TAG_LEN]; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class = ASN1_CLASS_PRIVATE; - else - class = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (is_tag_implicit) - _asn1_tag_der (class_implicit, tag_implicit, tag_der, - &tag_len); - else - _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, - _asn1_strtoul (p->value, NULL, 10), - tag_der, &tag_len); - - *max_len -= tag_len; - if (der && *max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; - - _asn1_ltostr (*counter, (char *) temp); - _asn1_set_name (p, (const char *) temp); - - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || - (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) - || (type_field (node->type) == ASN1_ETYPE_SET) - || (type_field (node->type) == ASN1_ETYPE_SET_OF)) - class |= ASN1_CLASS_STRUCTURED; - class_implicit = class; - tag_implicit = _asn1_strtoul (p->value, NULL, 10); - is_tag_implicit = 1; - } - } - } - p = p->right; - } - } - - if (is_tag_implicit) - { - _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); - } - else - { - unsigned type = type_field (node->type); - switch (type) - { - CASE_HANDLED_ETYPES: - _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag, - tag_der, &tag_len); - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - tag_len = 0; - break; - default: - return ASN1_GENERIC_ERROR; - } - } - - *max_len -= tag_len; - if (der && *max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; - - if (*max_len < 0) - return ASN1_MEM_ERROR; - - return ASN1_SUCCESS; -} - -/******************************************************/ -/* Function : _asn1_ordering_set */ -/* Description: puts the elements of a SET type in */ -/* the correct order according to DER rules. */ -/* Parameters: */ -/* der: string with the DER coding. */ -/* node: pointer to the SET element. */ -/* Return: */ -/* ASN1_SUCCESS if successful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) -{ - struct vet - { - int end; - unsigned long value; - struct vet *next, *prev; - }; - - int counter, len, len2; - struct vet *first, *last, *p_vet, *p2_vet; - asn1_node p; - unsigned char class, *temp; - unsigned long tag, t; - int err; - - counter = 0; - - if (type_field (node->type) != ASN1_ETYPE_SET) - return ASN1_VALUE_NOT_VALID; - - p = node->down; - while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || - (type_field (p->type) == ASN1_ETYPE_SIZE))) - p = p->right; - - if ((p == NULL) || (p->right == NULL)) - return ASN1_SUCCESS; - - first = last = NULL; - while (p) - { - p_vet = malloc (sizeof (struct vet)); - if (p_vet == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - - p_vet->next = NULL; - p_vet->prev = last; - if (first == NULL) - first = p_vet; - else - last->next = p_vet; - last = p_vet; - - /* tag value calculation */ - err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2, - &tag); - if (err != ASN1_SUCCESS) - goto error; - - t = ((unsigned int)class) << 24; - p_vet->value = t | tag; - counter += len2; - - /* extraction and length */ - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - counter += len + len2; - - p_vet->end = counter; - p = p->right; - } - - p_vet = first; - - while (p_vet) - { - p2_vet = p_vet->next; - counter = 0; - while (p2_vet) - { - if (p_vet->value > p2_vet->value) - { - /* change position */ - temp = malloc (p_vet->end - counter); - if (temp == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - - memcpy (temp, der + counter, p_vet->end - counter); - memcpy (der + counter, der + p_vet->end, - p2_vet->end - p_vet->end); - memcpy (der + counter + p2_vet->end - p_vet->end, temp, - p_vet->end - counter); - free (temp); - - tag = p_vet->value; - p_vet->value = p2_vet->value; - p2_vet->value = tag; - - p_vet->end = counter + (p2_vet->end - p_vet->end); - } - counter = p_vet->end; - - p2_vet = p2_vet->next; - p_vet = p_vet->next; - } - - if (p_vet != first) - p_vet->prev->next = NULL; - else - first = NULL; - free (p_vet); - p_vet = first; - } - return ASN1_SUCCESS; - -error: - while (first != NULL) - { - p_vet = first; - first = first->next; - free(p_vet); - } - return err; -} - -struct vet -{ - unsigned char *ptr; - int size; -}; - -static int setof_compar(const void *_e1, const void *_e2) -{ - unsigned length; - const struct vet *e1 = _e1, *e2 = _e2; - int rval; - - /* The encodings of the component values of a set-of value shall - * appear in ascending order, the encodings being compared - * as octet strings with the shorter components being - * padded at their trailing end with 0-octets. - * The padding octets are for comparison purposes and - * do not appear in the encodings. - */ - length = MIN(e1->size, e2->size); - - rval = memcmp(e1->ptr, e2->ptr, length); - if (rval == 0 && e1->size != e2->size) - { - if (e1->size > e2->size) - rval = 1; - else if (e2->size > e1->size) - rval = -1; - } - - return rval; -} - -/******************************************************/ -/* Function : _asn1_ordering_set_of */ -/* Description: puts the elements of a SET OF type in */ -/* the correct order according to DER rules. */ -/* Parameters: */ -/* der: string with the DER coding. */ -/* node: pointer to the SET OF element. */ -/* Return: */ -/* ASN1_SUCCESS if successful */ -/* or an error value. */ -/******************************************************/ -static int -_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) -{ - int counter, len, len2; - struct vet *list = NULL, *tlist; - unsigned list_size = 0; - struct vet *p_vet; - asn1_node p; - unsigned char class; - unsigned i; - unsigned char *out = NULL; - int err; - - if (der == NULL) - return ASN1_VALUE_NOT_VALID; - - counter = 0; - - if (type_field (node->type) != ASN1_ETYPE_SET_OF) - return ASN1_VALUE_NOT_VALID; - - p = node->down; - while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || - (type_field (p->type) == ASN1_ETYPE_SIZE))) - p = p->right; - if (p == NULL) - return ASN1_VALUE_NOT_VALID; - p = p->right; - - if ((p == NULL) || (p->right == NULL)) - return ASN1_SUCCESS; - - while (p) - { - list_size++; - tlist = realloc (list, list_size*sizeof(struct vet)); - if (tlist == NULL) - { - err = ASN1_MEM_ALLOC_ERROR; - goto error; - } - list = tlist; - p_vet = &list[list_size-1]; - - p_vet->ptr = der+counter; - p_vet->size = 0; - - /* extraction of tag and length */ - if (der_len - counter > 0) - { - err = asn1_get_tag_der (der + counter, der_len - counter, &class, - &len, NULL); - if (err != ASN1_SUCCESS) - goto error; - counter += len; - p_vet->size += len; - - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - counter += len + len2; - p_vet->size += len + len2; - - } - else - { - err = ASN1_DER_ERROR; - goto error; - } - p = p->right; - } - - if (counter > der_len) - { - err = ASN1_DER_ERROR; - goto error; - } - - qsort(list, list_size, sizeof(struct vet), setof_compar); - - out = malloc(der_len); - if (out == NULL) - { - err = ASN1_MEM_ERROR; - goto error; - } - - /* the sum of p_vet->size == der_len */ - counter = 0; - for (i = 0; i < list_size; i++) - { - p_vet = &list[i]; - memcpy(out+counter, p_vet->ptr, p_vet->size); - counter += p_vet->size; - } - memcpy(der, out, der_len); - free(out); - - err = ASN1_SUCCESS; - -error: - free(list); - return err; -} - -/** - * asn1_der_coding: - * @element: pointer to an ASN1 element - * @name: the name of the structure you want to encode (it must be - * inside *POINTER). - * @ider: vector that will contain the DER encoding. DER must be a - * pointer to memory cells already allocated. - * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy - * holds the sizeof of der vector. - * @ErrorDescription: return the error description or an empty - * string if success. - * - * Creates the DER encoding for the NAME structure (inside *POINTER - * structure). - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there - * is an element without a value, %ASN1_MEM_ERROR if the @ider - * vector isn't big enough and in this case @len will contain the - * length needed. - **/ -int -asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len, - char *ErrorDescription) -{ - asn1_node node, p, p2; - unsigned char temp[MAX(LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; - int counter, counter_old, len2, len3, move, max_len, max_len_old; - int err; - unsigned char *der = ider; - - if (ErrorDescription) - ErrorDescription[0] = 0; - - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - /* Node is now a locally allocated variable. - * That is because in some point we modify the - * structure, and I don't know why! --nmav - */ - node = _asn1_copy_structure3 (node); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - max_len = *len; - - if (der == NULL && max_len > 0) - return ASN1_VALUE_NOT_VALID; - - counter = 0; - move = DOWN; - p = node; - - while (1) - { - - counter_old = counter; - max_len_old = max_len; - if (move != UP) - { - p->start = counter; - err = _asn1_insert_tag_der (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - } - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - max_len--; - if (der != NULL && max_len >= 0) - der[counter] = 0; - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - max_len -= 2; - if (der != NULL && max_len >= 0) - { - der[counter++] = 1; - if (p->value[0] == 'F') - der[counter++] = 0; - else - der[counter++] = 0xFF; - } - else - counter += 2; - } - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2 + len3; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value, len3 + len2); - counter += len3 + len2; - } - move = RIGHT; - break; - case ASN1_ETYPE_OBJECT_ID: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = _asn1_object_id_der ((char*)p->value, der + counter, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len -= len2; - counter += len2; - } - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = _asn1_time_der (p->value, p->value_len, der + counter, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len -= len2; - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2 + len3; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move != UP) - { - p->tmp_ival = counter; - if (p->down == NULL) - { - move = UP; - continue; - } - else - { - p2 = p->down; - while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG)) - p2 = p2->right; - if (p2) - { - p = p2; - move = RIGHT; - continue; - } - move = UP; - continue; - } - } - else - { /* move==UP */ - len2 = p->tmp_ival; - p->tmp_ival = 0; - if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0)) - { - err = _asn1_ordering_set (der + len2, counter - len2, p); - if (err != ASN1_SUCCESS) - goto error; - } - asn1_length_der (counter - len2, temp, &len3); - max_len -= len3; - if (der != NULL && max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); - } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move != UP) - { - p->tmp_ival = counter; - p = p->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - if (p->right) - { - p = p->right; - move = RIGHT; - continue; - } - else - p = _asn1_find_up (p); - move = UP; - } - if (move == UP) - { - len2 = p->tmp_ival; - p->tmp_ival = 0; - if ((type_field (p->type) == ASN1_ETYPE_SET_OF) - && (counter - len2 > 0) && (max_len >= 0)) - { - err = _asn1_ordering_set_of (der + len2, counter - len2, p); - if (err != ASN1_SUCCESS) - goto error; - } - asn1_length_der (counter - len2, temp, &len3); - max_len -= len3; - if (der != NULL && max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); - } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_ANY: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - if (len2 < 0) - { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2; - if (der != NULL && max_len >= 0) - memcpy (der + counter, p->value + len3, len2); - counter += len2; - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - - if ((move != DOWN) && (counter != counter_old)) - { - p->end = counter - 1; - err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - } - - if (p == node && move != DOWN) - break; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - *len = counter; - - if (max_len < 0) - { - err = ASN1_MEM_ERROR; - goto error; - } - - err = ASN1_SUCCESS; - -error: - asn1_delete_structure (&node); - return err; -} diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c deleted file mode 100644 index ff04eb7..0000000 --- a/lib/minitasn1/decoding.c +++ /dev/null @@ -1,2478 +0,0 @@ -/* - * Copyright (C) 2002-2016 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - - -/*****************************************************/ -/* File: decoding.c */ -/* Description: Functions to manage DER decoding */ -/*****************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) -#else -# define warn() -#endif - -#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) && len < 0)) - -#define HAVE_TWO(x) (x>=2?1:0) - -/* Decoding flags (dflags) used in several decoding functions. - * DECODE_FLAG_HAVE_TAG: The provided buffer includes a tag - * DECODE_FLAG_CONSTRUCTED: The provided buffer is of indefinite encoding (useful - * when no tags are present). - * DECODE_FLAG_LEVEL1: Internal flag to indicate a level of recursion for BER strings. - * DECODE_FLAG_LEVEL2: Internal flag to indicate two levels of recursion for BER strings. - * DECODE_FLAG_LEVEL3: Internal flag to indicate three levels of recursion for BER strings. - * This is the maximum levels of recursion possible to prevent stack - * exhaustion. - */ - -#define DECODE_FLAG_HAVE_TAG 1 -#define DECODE_FLAG_CONSTRUCTED (1<<1) -#define DECODE_FLAG_LEVEL1 (1<<2) -#define DECODE_FLAG_LEVEL2 (1<<3) -#define DECODE_FLAG_LEVEL3 (1<<4) - -#define DECR_LEN(l, s) do { \ - l -= s; \ - if (l < 0) { \ - warn(); \ - result = ASN1_DER_ERROR; \ - goto cleanup; \ - } \ - } while (0) - -static int -_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len); - -static int -_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len, - unsigned dflags); - -static int -_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len, unsigned dflags); - -static void -_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) -{ - - Estrcpy (ErrorDescription, ":: tag error near element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "'"); - -} - -/** - * asn1_get_length_der: - * @der: DER data to decode. - * @der_len: Length of DER data to decode. - * @len: Output variable containing the length of the DER length field. - * - * Extract a length field from DER data. - * - * Returns: Return the decoded length value, or -1 on indefinite - * length, or -2 when the value was too big to fit in a int, or -4 - * when the decoded length value plus @len would exceed @der_len. - **/ -long -asn1_get_length_der (const unsigned char *der, int der_len, int *len) -{ - unsigned int ans; - int k, punt, sum; - - *len = 0; - if (der_len <= 0) - return 0; - - if (!(der[0] & 128)) - { - /* short form */ - *len = 1; - ans = der[0]; - } - else - { - /* Long form */ - k = der[0] & 0x7F; - punt = 1; - if (k) - { /* definite length method */ - ans = 0; - while (punt <= k && punt < der_len) - { - if (INT_MULTIPLY_OVERFLOW (ans, 256)) - return -2; - ans *= 256; - - if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt]))) - return -2; - ans += der[punt]; - punt++; - } - } - else - { /* indefinite length method */ - *len = punt; - return -1; - } - - *len = punt; - } - - sum = ans; - if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len))) - return -2; - sum += *len; - - if (sum > der_len) - return -4; - - return ans; -} - -/** - * asn1_get_tag_der: - * @der: DER data to decode. - * @der_len: Length of DER data to decode. - * @cls: Output variable containing decoded class. - * @len: Output variable containing the length of the DER TAG data. - * @tag: Output variable containing the decoded tag (may be %NULL). - * - * Decode the class and TAG from DER code. - * - * Returns: Returns %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag) -{ - unsigned int ris; - int punt; - - if (der == NULL || der_len < 2 || len == NULL) - return ASN1_DER_ERROR; - - *cls = der[0] & 0xE0; - if ((der[0] & 0x1F) != 0x1F) - { - /* short form */ - *len = 1; - ris = der[0] & 0x1F; - } - else - { - /* Long form */ - punt = 1; - ris = 0; - while (punt < der_len && der[punt] & 128) - { - - if (INT_MULTIPLY_OVERFLOW (ris, 128)) - return ASN1_DER_ERROR; - ris *= 128; - - if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) - return ASN1_DER_ERROR; - ris += (der[punt] & 0x7F); - punt++; - } - - if (punt >= der_len) - return ASN1_DER_ERROR; - - if (INT_MULTIPLY_OVERFLOW (ris, 128)) - return ASN1_DER_ERROR; - ris *= 128; - - if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F)))) - return ASN1_DER_ERROR; - ris += (der[punt] & 0x7F); - punt++; - - *len = punt; - } - - if (tag) - *tag = ris; - return ASN1_SUCCESS; -} - -/** - * asn1_get_length_ber: - * @ber: BER data to decode. - * @ber_len: Length of BER data to decode. - * @len: Output variable containing the length of the BER length field. - * - * Extract a length field from BER data. The difference to - * asn1_get_length_der() is that this function will return a length - * even if the value has indefinite encoding. - * - * Returns: Return the decoded length value, or negative value when - * the value was too big. - * - * Since: 2.0 - **/ -long -asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len) -{ - int ret; - long err; - - ret = asn1_get_length_der (ber, ber_len, len); - - if (ret == -1 && ber_len > 1) - { /* indefinite length method */ - err = _asn1_get_indefinite_length_string (ber + 1, ber_len-1, &ret); - if (err != ASN1_SUCCESS) - return -3; - } - - return ret; -} - -/** - * asn1_get_octet_der: - * @der: DER data to decode containing the OCTET SEQUENCE. - * @der_len: The length of the @der data to decode. - * @ret_len: Output variable containing the encoded length of the DER data. - * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in. - * @str_size: Length of pre-allocated output buffer. - * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE. - * - * Extract an OCTET SEQUENCE from DER data. Note that this function - * expects the DER data past the tag field, i.e., the length and - * content octets. - * - * Returns: Returns %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *str_len) -{ - int len_len = 0; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - *str_len = asn1_get_length_der (der, der_len, &len_len); - - if (*str_len < 0) - return ASN1_DER_ERROR; - - *ret_len = *str_len + len_len; - if (str_size >= *str_len) - { - if (*str_len > 0 && str != NULL) - memcpy (str, der + len_len, *str_len); - } - else - { - return ASN1_MEM_ERROR; - } - - return ASN1_SUCCESS; -} - - -/*- - * _asn1_get_time_der: - * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME - * @der: DER data to decode containing the time - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put the textual time in. - * @str_size: Length of pre-allocated output buffer. - * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER - * - * Performs basic checks in the DER encoded time object and returns its textual form. - * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime - * and YYMMDD000000Z for UTCTime. - * - * Returns: %ASN1_SUCCESS on success, or an error. - -*/ -static int -_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len, - char *str, int str_size, unsigned flags) -{ - int len_len, str_len; - unsigned i; - unsigned sign_count = 0; - unsigned dot_count = 0; - const unsigned char *p; - - if (der_len <= 0 || str == NULL) - return ASN1_DER_ERROR; - - str_len = asn1_get_length_der (der, der_len, &len_len); - if (str_len <= 0 || str_size < str_len) - return ASN1_DER_ERROR; - - /* perform some sanity checks on the data */ - if (str_len < 8) - { - warn(); - return ASN1_TIME_ENCODING_ERROR; - } - - if ((flags & ASN1_DECODE_FLAG_STRICT_DER) && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)) - { - p = &der[len_len]; - for (i=0;i<(unsigned)(str_len-1);i++) - { - if (c_isdigit(p[i]) == 0) - { - if (type == ASN1_ETYPE_GENERALIZED_TIME) - { - /* tolerate lax encodings */ - if (p[i] == '.' && dot_count == 0) - { - dot_count++; - continue; - } - - /* This is not really valid DER, but there are - * structures using that */ - if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && - (p[i] == '+' || p[i] == '-') && sign_count == 0) - { - sign_count++; - continue; - } - } - - warn(); - return ASN1_TIME_ENCODING_ERROR; - } - } - - if (sign_count == 0 && p[str_len-1] != 'Z') - { - warn(); - return ASN1_TIME_ENCODING_ERROR; - } - } - memcpy (str, der + len_len, str_len); - str[str_len] = 0; - *ret_len = str_len + len_len; - - return ASN1_SUCCESS; -} - -/** - * asn1_get_object_id_der: - * @der: DER data to decode containing the OBJECT IDENTIFIER - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put the textual object id in. - * @str_size: Length of pre-allocated output buffer. - * - * Converts a DER encoded object identifier to its textual form. This - * function expects the DER object identifier without the tag. - * - * Returns: %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len, - char *str, int str_size) -{ - int len_len, len, k; - int leading, parsed; - char temp[LTOSTR_MAX_SIZE]; - uint64_t val, val1, val0; - - *ret_len = 0; - if (str && str_size > 0) - str[0] = 0; /* no oid */ - - if (str == NULL || der_len <= 0) - return ASN1_GENERIC_ERROR; - - len = asn1_get_length_der (der, der_len, &len_len); - - if (len <= 0 || len + len_len > der_len) - return ASN1_DER_ERROR; - - /* leading octet can never be 0x80 */ - if (der[len_len] == 0x80) - return ASN1_DER_ERROR; - - val0 = 0; - - for (k = 0; k < len; k++) - { - if (INT_LEFT_SHIFT_OVERFLOW (val0, 7)) - return ASN1_DER_ERROR; - - val0 <<= 7; - val0 |= der[len_len + k] & 0x7F; - if (!(der[len_len + k] & 0x80)) - break; - } - parsed = ++k; - - /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */ - /* X = val, Y = val1 */ - - /* check if X == 0 */ - val = 0; - val1 = val0; - if (val1 > 39) - { - val = 1; - val1 = val0 - 40; - if (val1 > 39) - { - val = 2; - val1 = val0 - 80; - } - } - - _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp)); - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp)); - - val = 0; - leading = 1; - for (k = parsed; k < len; k++) - { - /* X.690 mandates that the leading byte must never be 0x80 - */ - if (leading != 0 && der[len_len + k] == 0x80) - return ASN1_DER_ERROR; - leading = 0; - - /* check for wrap around */ - if (INT_LEFT_SHIFT_OVERFLOW (val, 7)) - return ASN1_DER_ERROR; - - val = val << 7; - val |= der[len_len + k] & 0x7F; - - if (!(der[len_len + k] & 0x80)) - { - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); - val = 0; - leading = 1; - } - } - - if (INT_ADD_OVERFLOW (len, len_len)) - return ASN1_DER_ERROR; - - *ret_len = len + len_len; - - return ASN1_SUCCESS; -} - -/** - * asn1_get_bit_der: - * @der: DER data to decode containing the BIT SEQUENCE. - * @der_len: Length of DER data to decode. - * @ret_len: Output variable containing the length of the DER data. - * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in. - * @str_size: Length of pre-allocated output buffer. - * @bit_len: Output variable containing the size of the BIT SEQUENCE. - * - * Extract a BIT SEQUENCE from DER data. - * - * Returns: %ASN1_SUCCESS on success, or an error. - **/ -int -asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *bit_len) -{ - int len_len = 0, len_byte; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; - if (len_byte < 0) - return ASN1_DER_ERROR; - - *ret_len = len_byte + len_len + 1; - *bit_len = len_byte * 8 - der[len_len]; - - if (*bit_len < 0) - return ASN1_DER_ERROR; - - if (str_size >= len_byte) - { - if (len_byte > 0 && str) - memcpy (str, der + len_len + 1, len_byte); - } - else - { - return ASN1_MEM_ERROR; - } - - return ASN1_SUCCESS; -} - -/* tag_len: the total tag length (explicit+inner) - * inner_tag_len: the inner_tag length - */ -static int -_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len, - int *tag_len, int *inner_tag_len, unsigned flags) -{ - asn1_node p; - int counter, len2, len3, is_tag_implicit; - int result; - unsigned long tag, tag_implicit = 0; - unsigned char class, class2, class_implicit = 0; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - counter = is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class2 = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class2 = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class2 = ASN1_CLASS_PRIVATE; - else - class2 = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN(der_len, len2); - counter += len2; - - if (flags & ASN1_DECODE_FLAG_STRICT_DER) - len3 = - asn1_get_length_der (der + counter, der_len, - &len2); - else - len3 = - asn1_get_length_ber (der + counter, der_len, - &len2); - if (len3 < 0) - return ASN1_DER_ERROR; - - DECR_LEN(der_len, len2); - counter += len2; - - if (!is_tag_implicit) - { - if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || - (tag != strtoul ((char *) p->value, NULL, 10))) - return ASN1_TAG_ERROR; - } - else - { /* ASN1_TAG_IMPLICIT */ - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - is_tag_implicit = 0; - } - else - { /* ASN1_TAG_IMPLICIT */ - if (!is_tag_implicit) - { - if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || - (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) - || (type_field (node->type) == ASN1_ETYPE_SET) - || (type_field (node->type) == ASN1_ETYPE_SET_OF)) - class2 |= ASN1_CLASS_STRUCTURED; - class_implicit = class2; - tag_implicit = strtoul ((char *) p->value, NULL, 10); - is_tag_implicit = 1; - } - } - } - p = p->right; - } - } - - if (is_tag_implicit) - { - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN(der_len, len2); - - if ((class != class_implicit) || (tag != tag_implicit)) - { - if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING) - { - class_implicit |= ASN1_CLASS_STRUCTURED; - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - else - return ASN1_TAG_ERROR; - } - } - else - { - unsigned type = type_field (node->type); - if (type == ASN1_ETYPE_TAG) - { - *tag_len = 0; - if (inner_tag_len) - *inner_tag_len = 0; - return ASN1_SUCCESS; - } - - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN(der_len, len2); - - switch (type) - { - case ASN1_ETYPE_NULL: - case ASN1_ETYPE_BOOLEAN: - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - case ASN1_ETYPE_OBJECT_ID: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET: - case ASN1_ETYPE_SET_OF: - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if ((class != _asn1_tags[type].class) - || (tag != _asn1_tags[type].tag)) - return ASN1_DER_ERROR; - break; - - case ASN1_ETYPE_OCTET_STRING: - /* OCTET STRING is handled differently to allow - * BER encodings (structured class). */ - if (((class != ASN1_CLASS_UNIVERSAL) - && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))) - || (tag != ASN1_TAG_OCTET_STRING)) - return ASN1_DER_ERROR; - break; - case ASN1_ETYPE_ANY: - counter -= len2; - break; - case ASN1_ETYPE_CHOICE: - counter -= len2; - break; - default: - return ASN1_DER_ERROR; - break; - } - } - - counter += len2; - *tag_len = counter; - if (inner_tag_len) - *inner_tag_len = len2; - return ASN1_SUCCESS; - -cleanup: - return result; -} - -static int -extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len, - int *ret_len, int *inner_len, unsigned flags) -{ -asn1_node p; -int ris = ASN1_DER_ERROR; - - if (type_field (node->type) == ASN1_ETYPE_CHOICE) - { - p = node->down; - while (p) - { - ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags); - if (ris == ASN1_SUCCESS) - break; - p = p->right; - } - - *ret_len = 0; - return ris; - } - else - return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags); -} - -static int -_asn1_delete_not_used (asn1_node node) -{ - asn1_node p, p2; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (p->type & CONST_NOT_USED) - { - p2 = NULL; - if (p != node) - { - p2 = _asn1_find_left (p); - if (!p2) - p2 = _asn1_find_up (p); - } - asn1_delete_structure (&p); - p = p2; - } - - if (!p) - break; /* reach node */ - - if (p->down) - { - p = p->down; - } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - } - return ASN1_SUCCESS; -} - -static int -_asn1_get_indefinite_length_string (const unsigned char *der, - int der_len, int *len) -{ - int len2, len3, counter, indefinite; - int result; - unsigned long tag; - unsigned char class; - - counter = indefinite = 0; - - while (1) - { - if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0)) - { - counter += 2; - DECR_LEN(der_len, 2); - - indefinite--; - if (indefinite <= 0) - break; - else - continue; - } - - if (asn1_get_tag_der - (der + counter, der_len, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - DECR_LEN(der_len, len2); - counter += len2; - - len2 = asn1_get_length_der (der + counter, der_len, &len3); - if (len2 < -1) - return ASN1_DER_ERROR; - - if (len2 == -1) - { - indefinite++; - counter += 1; - DECR_LEN(der_len, 1); - } - else - { - counter += len2 + len3; - DECR_LEN(der_len, len2+len3); - } - } - - *len = counter; - return ASN1_SUCCESS; - -cleanup: - return result; -} - -static void delete_unneeded_choice_fields(asn1_node p) -{ - asn1_node p2; - - while (p->right) - { - p2 = p->right; - asn1_delete_structure (&p2); - } -} - - -/** - * asn1_der_decoding2 - * @element: pointer to an ASN1 structure. - * @ider: vector that contains the DER encoding. - * @max_ider_len: pointer to an integer giving the information about the - * maximal number of bytes occupied by *@ider. The real size of the DER - * encoding is returned through this pointer. - * @flags: flags controlling the behaviour of the function. - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the structure *@element with values of a DER encoding string. The - * structure must just be created with function asn1_create_element(). - * - * If %ASN1_DECODE_FLAG_ALLOW_PADDING flag is set then the function will ignore - * padding after the decoded DER data. Upon a successful return the value of - * *@max_ider_len will be set to the number of bytes decoded. - * - * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will - * not decode any BER-encoded elements. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or - * %ASN1_DER_ERROR if the der encoding doesn't match the structure - * name (*@ELEMENT deleted). - **/ -int -asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len, - unsigned int flags, char *errorDescription) -{ - asn1_node node, p, p2, p3; - char temp[128]; - int counter, len2, len3, len4, move, ris, tlen; - struct node_tail_cache_st tcache = {NULL, NULL}; - unsigned char class; - unsigned long tag; - int tag_len; - int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len; - int inner_tag_len; - unsigned char *ptmp; - const unsigned char *ptag; - const unsigned char *der = ider; - - node = *element; - - if (errorDescription != NULL) - errorDescription[0] = 0; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (node->type & CONST_OPTION) - { - result = ASN1_GENERIC_ERROR; - warn(); - goto cleanup; - } - - counter = 0; - move = DOWN; - p = node; - while (1) - { - tag_len = 0; - inner_tag_len = 0; - ris = ASN1_SUCCESS; - if (move != UP) - { - if (p->type & CONST_SET) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - if (len2 == -1) - { - if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1]) - { - p = p2; - move = UP; - counter += 2; - DECR_LEN(ider_len, 2); - continue; - } - } - else if (counter == len2) - { - p = p2; - move = UP; - continue; - } - else if (counter > len2) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - p2 = p2->down; - while (p2) - { - if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) - { - ris = - extract_tag_der_recursive (p2, der + counter, - ider_len, &len2, NULL, flags); - if (ris == ASN1_SUCCESS) - { - p2->type &= ~CONST_NOT_USED; - p = p2; - break; - } - } - p2 = p2->right; - } - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - } - - /* the position in the DER structure this starts */ - p->start = counter; - p->end = total_len - 1; - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - if (counter == len2) - { - if (p->right) - { - p2 = p->right; - move = RIGHT; - } - else - move = UP; - - if (p->type & CONST_OPTION) - asn1_delete_structure (&p); - - p = p2; - continue; - } - } - - if (type_field (p->type) == ASN1_ETYPE_CHOICE) - { - while (p->down) - { - ris = - extract_tag_der_recursive (p->down, der + counter, - ider_len, &len2, NULL, flags); - - if (ris == ASN1_SUCCESS) - { - delete_unneeded_choice_fields(p->down); - break; - } - else if (ris == ASN1_ERROR_TYPE_ANY) - { - result = ASN1_ERROR_TYPE_ANY; - warn(); - goto cleanup; - } - else - { - p2 = p->down; - asn1_delete_structure (&p2); - } - } - - if (p->down == NULL) - { - if (!(p->type & CONST_OPTION)) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - } - else if (type_field (p->type) != ASN1_ETYPE_CHOICE) - p = p->down; - - p->start = counter; - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = p2->tmp_ival; - - if ((len2 != -1) && (counter > len2)) - ris = ASN1_TAG_ERROR; - } - - if (ris == ASN1_SUCCESS) - ris = - extract_tag_der_recursive (p, der + counter, ider_len, - &tag_len, &inner_tag_len, flags); - - if (ris != ASN1_SUCCESS) - { - if (p->type & CONST_OPTION) - { - p->type |= CONST_NOT_USED; - move = RIGHT; - } - else if (p->type & CONST_DEFAULT) - { - _asn1_set_value (p, NULL, 0); - move = RIGHT; - } - else - { - if (errorDescription != NULL) - _asn1_error_description_tag_error (p, errorDescription); - - result = ASN1_TAG_ERROR; - warn(); - goto cleanup; - } - } - else - { - DECR_LEN(ider_len, tag_len); - counter += tag_len; - } - } - - if (ris == ASN1_SUCCESS) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - DECR_LEN(ider_len, 1); - if (der[counter]) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - DECR_LEN(ider_len, 2); - - if (der[counter++] != 1) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - if (der[counter++] == 0) - _asn1_set_value (p, "F", 1); - else - _asn1_set_value (p, "T", 1); - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - len2 = - asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len3+len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_OBJECT_ID: - result = - asn1_get_object_id_der (der + counter, ider_len, &len2, - temp, sizeof (temp)); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - result = - _asn1_get_time_der (type_field (p->type), der + counter, ider_len, &len2, temp, - sizeof (temp) - 1, flags); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen); - - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - if (counter < inner_tag_len) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - ptag = der + counter - inner_tag_len; - if ((flags & ASN1_DECODE_FLAG_STRICT_DER) || !(ptag[0] & ASN1_CLASS_STRUCTURED)) - { - if (ptag[0] & ASN1_CLASS_STRUCTURED) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - len2 = - asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len3+len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - } - else - { - unsigned dflags = 0, vlen, ber_len; - - if (ptag[0] & ASN1_CLASS_STRUCTURED) - dflags |= DECODE_FLAG_CONSTRUCTED; - - result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, ber_len); - - _asn1_set_value_lv (p, ptmp, vlen); - - counter += ber_len; - free(ptmp); - } - move = RIGHT; - break; - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - case ASN1_ETYPE_BIT_STRING: - len2 = - asn1_get_length_der (der + counter, ider_len, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len3+len2); - - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move == UP) - { - len2 = p->tmp_ival; - p->tmp_ival = 0; - if (len2 == -1) - { /* indefinite length method */ - DECR_LEN(ider_len, 2); - if ((der[counter]) || der[counter + 1]) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - counter += 2; - } - else - { /* definite length method */ - if (len2 != counter) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - } - move = RIGHT; - } - else - { /* move==DOWN || move==RIGHT */ - len3 = - asn1_get_length_der (der + counter, ider_len, &len2); - if (IS_ERR(len3, flags)) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - counter += len2; - - if (len3 > 0) - { - p->tmp_ival = counter + len3; - move = DOWN; - } - else if (len3 == 0) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p3 = p2->right; - asn1_delete_structure (&p2); - p2 = p3; - } - else - p2 = p2->right; - } - move = RIGHT; - } - else - { /* indefinite length method */ - p->tmp_ival = -1; - move = DOWN; - } - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move == UP) - { - len2 = p->tmp_ival; - if (len2 == -1) - { /* indefinite length method */ - if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1])) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn(); - goto cleanup; - } - p = tcache.tail; - move = RIGHT; - continue; - } - - p->tmp_ival = 0; - tcache.tail = NULL; /* finished decoding this structure */ - tcache.head = NULL; - DECR_LEN(ider_len, 2); - counter += 2; - } - else - { /* definite length method */ - if (len2 > counter) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn(); - goto cleanup; - } - p = tcache.tail; - move = RIGHT; - continue; - } - - p->tmp_ival = 0; - tcache.tail = NULL; /* finished decoding this structure */ - tcache.head = NULL; - - if (len2 != counter) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - } - } - else - { /* move==DOWN || move==RIGHT */ - len3 = - asn1_get_length_der (der + counter, ider_len, &len2); - if (IS_ERR(len3, flags)) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - counter += len2; - if (len3) - { - if (len3 > 0) - { /* definite length method */ - p->tmp_ival = counter + len3; - } - else - { /* indefinite length method */ - p->tmp_ival = -1; - } - - p2 = p->down; - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - while ((type_field (p2->type) == ASN1_ETYPE_TAG) - || (type_field (p2->type) == ASN1_ETYPE_SIZE)) - p2 = p2->right; - if (p2->right == NULL) - { - result = _asn1_append_sequence_set (p, &tcache); - if (result != 0) - { - warn(); - goto cleanup; - } - } - p = p2; - } - } - move = RIGHT; - break; - case ASN1_ETYPE_ANY: - /* Check indefinite lenth method in an EXPLICIT TAG */ - - if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && (p->type & CONST_TAG) && - tag_len == 2 && (der[counter - 1] == 0x80)) - indefinite = 1; - else - indefinite = 0; - - if (asn1_get_tag_der - (der + counter, ider_len, &class, &len2, - &tag) != ASN1_SUCCESS) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - - len4 = - asn1_get_length_der (der + counter + len2, - ider_len, &len3); - if (IS_ERR(len4, flags)) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - if (len4 != -1) /* definite */ - { - len2 += len4; - - DECR_LEN(ider_len, len4+len3); - _asn1_set_value_lv (p, der + counter, len2 + len3); - counter += len2 + len3; - } - else /* == -1 */ - { /* indefinite length */ - ider_len += len2; /* undo DECR_LEN */ - - if (counter == 0) - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - - result = - _asn1_get_indefinite_length_string (der + counter, ider_len, &len2); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - DECR_LEN(ider_len, len2); - _asn1_set_value_lv (p, der + counter, len2); - counter += len2; - - } - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if (indefinite) - { - DECR_LEN(ider_len, 2); - if (!der[counter] && !der[counter + 1]) - { - counter += 2; - } - else - { - result = ASN1_DER_ERROR; - warn(); - goto cleanup; - } - } - - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - } - - if (p) - { - p->end = counter - 1; - } - - if (p == node && move != DOWN) - break; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if ((move == RIGHT) && !(p->type & CONST_SET)) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - _asn1_delete_not_used (*element); - - if ((ider_len < 0) || - (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0))) - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - - *max_ider_len = total_len - ider_len; - - return ASN1_SUCCESS; - -cleanup: - asn1_delete_structure (element); - return result; -} - - -/** - * asn1_der_decoding: - * @element: pointer to an ASN1 structure. - * @ider: vector that contains the DER encoding. - * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]. - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the structure *@element with values of a DER encoding - * string. The structure must just be created with function - * asn1_create_element(). - * - * Note that the *@element variable is provided as a pointer for - * historical reasons. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or - * %ASN1_DER_ERROR if the der encoding doesn't match the structure - * name (*@ELEMENT deleted). - **/ -int -asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, - char *errorDescription) -{ - return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); -} - -/** - * asn1_der_decoding_element: - * @structure: pointer to an ASN1 structure - * @elementName: name of the element to fill - * @ider: vector that contains the DER encoding of the whole structure. - * @len: number of bytes of *der: der[0]..der[len-1] - * @errorDescription: null-terminated string contains details when an - * error occurred. - * - * Fill the element named @ELEMENTNAME with values of a DER encoding - * string. The structure must just be created with function - * asn1_create_element(). The DER vector must contain the encoding - * string of the whole @STRUCTURE. If an error occurs during the - * decoding procedure, the *@STRUCTURE is deleted and set equal to - * %NULL. - * - * This function is deprecated and may just be an alias to asn1_der_decoding - * in future versions. Use asn1_der_decoding() instead. - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if ELEMENT is %NULL or @elementName == NULL, and - * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't - * match the structure @structure (*ELEMENT deleted). - **/ -int -asn1_der_decoding_element (asn1_node * structure, const char *elementName, - const void *ider, int len, char *errorDescription) -{ - return asn1_der_decoding(structure, ider, len, errorDescription); -} - -/** - * asn1_der_decoding_startEnd: - * @element: pointer to an ASN1 element - * @ider: vector that contains the DER encoding. - * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1] - * @name_element: an element of NAME structure. - * @start: the position of the first byte of NAME_ELEMENT decoding - * (@ider[*start]) - * @end: the position of the last byte of NAME_ELEMENT decoding - * (@ider[*end]) - * - * Find the start and end point of an element in a DER encoding - * string. I mean that if you have a der encoding and you have already - * used the function asn1_der_decoding() to fill a structure, it may - * happen that you want to find the piece of string concerning an - * element of the structure. - * - * One example is the sequence "tbsCertificate" inside an X509 - * certificate. - * - * Note that since libtasn1 3.7 the @ider and @ider_len parameters - * can be omitted, if the element is already decoded using asn1_der_decoding(). - * - * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND - * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid - * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding - * doesn't match the structure ELEMENT. - **/ -int -asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len, - const char *name_element, int *start, int *end) -{ - asn1_node node, node_to_find; - int result = ASN1_DER_ERROR; - - node = element; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - node_to_find = asn1_find_node (node, name_element); - - if (node_to_find == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - *start = node_to_find->start; - *end = node_to_find->end; - - if (*start == 0 && *end == 0) - { - if (ider == NULL || ider_len == 0) - return ASN1_GENERIC_ERROR; - - /* it seems asn1_der_decoding() wasn't called before. Do it now */ - result = asn1_der_decoding (&node, ider, ider_len, NULL); - if (result != ASN1_SUCCESS) - { - warn(); - return result; - } - - node_to_find = asn1_find_node (node, name_element); - if (node_to_find == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - *start = node_to_find->start; - *end = node_to_find->end; - } - - if (*end < *start) - return ASN1_GENERIC_ERROR; - - return ASN1_SUCCESS; -} - -/** - * asn1_expand_any_defined_by: - * @definitions: ASN1 definitions - * @element: pointer to an ASN1 structure - * - * Expands every "ANY DEFINED BY" element of a structure created from - * a DER decoding process (asn1_der_decoding function). The element - * ANY must be defined by an OBJECT IDENTIFIER. The type used to - * expand the element ANY is the first one following the definition of - * the actual value of the OBJECT IDENTIFIER. - * - * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if - * some "ANY DEFINED BY" element couldn't be expanded due to a - * problem in OBJECT_ID -> TYPE association, or other error codes - * depending on DER decoding. - **/ -int -asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 2], - value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node_const p2; - asn1_node p, p3, aux = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - const char *definitionsName; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - definitionsName = definitions->name; - - p = *element; - while (p) - { - - switch (type_field (p->type)) - { - case ASN1_ETYPE_ANY: - if ((p->type & CONST_DEFINED_BY) && (p->value)) - { - /* search the "DEF_BY" element */ - p2 = p->down; - while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT)) - p2 = p2->right; - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = _asn1_find_up (p); - - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = p3->down; - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } - - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - (p3->value == NULL)) - { - - p3 = _asn1_find_up (p); - p3 = _asn1_find_up (p3); - - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = p3->down; - - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } - - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) - || (p3->value == NULL)) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - } - - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); - - len = ASN1_MAX_NAME_SIZE; - result = - asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (p3->value, value))) - { - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); - - result = - asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, p); - len2 = - asn1_get_length_der (p->value, - p->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, p->value + len3, - len2, - errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, p->right); - _asn1_set_right (p, aux); - - result = asn1_delete_structure (&p); - if (result == ASN1_SUCCESS) - { - p = aux; - aux = NULL; - break; - } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; - } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; - } - } - else - { /* error with asn1_create_element */ - retCode = result; - break; - } - } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - } - } - p2 = p2->right; - } /* end while */ - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - } - break; - default: - break; - } - - - if (p->down) - { - p = p->down; - } - else if (p == *element) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == *element) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - - return retCode; -} - -/** - * asn1_expand_octet_string: - * @definitions: ASN1 definitions - * @element: pointer to an ASN1 structure - * @octetName: name of the OCTECT STRING field to expand. - * @objectName: name of the OBJECT IDENTIFIER field to use to define - * the type for expansion. - * - * Expands an "OCTET STRING" element of a structure created from a DER - * decoding process (the asn1_der_decoding() function). The type used - * for expansion is the first one following the definition of the - * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME. - * - * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND - * if @objectName or @octetName are not correct, - * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to - * use for expansion, or other errors depending on DER decoding. - **/ -int -asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, - const char *octetName, const char *objectName) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node_const p2; - asn1_node aux = NULL; - asn1_node octetNode = NULL, objectNode = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - octetNode = asn1_find_node (*element, octetName); - if (octetNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING) - return ASN1_ELEMENT_NOT_FOUND; - if (octetNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - objectNode = asn1_find_node (*element, objectName); - if (objectNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID) - return ASN1_ELEMENT_NOT_FOUND; - - if (objectNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - len = sizeof (value); - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (objectNode->value, value))) - { - - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - result = asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, octetNode); - len2 = - asn1_get_length_der (octetNode->value, - octetNode->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, octetNode->value + len3, - len2, errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, octetNode->right); - _asn1_set_right (octetNode, aux); - - result = asn1_delete_structure (&octetNode); - if (result == ASN1_SUCCESS) - { - aux = NULL; - break; - } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; - } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; - } - } - else - { /* error with asn1_create_element */ - retCode = result; - break; - } - } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_VALUE_NOT_VALID; - break; - } - } - } - - p2 = p2->right; - - } - - if (!p2) - retCode = ASN1_VALUE_NOT_VALID; - - return retCode; -} - -/*- - * _asn1_decode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @dflags: DECODE_FLAG_* - * - * Decodes a simple DER encoded type (e.g. a string, which is not constructed). - * The output is a pointer inside the @der. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - -*/ -static int -_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len, unsigned dflags) -{ - int tag_len, len_len; - const unsigned char *p; - int der_len = _der_len; - unsigned char class; - unsigned long tag; - long ret; - - if (der == NULL || der_len == 0) - return ASN1_VALUE_NOT_VALID; - - if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0) - return ASN1_VALUE_NOT_VALID; - - /* doesn't handle constructed classes */ - class = ETYPE_CLASS(etype); - if (class != ASN1_CLASS_UNIVERSAL) - return ASN1_VALUE_NOT_VALID; - - p = der; - - if (dflags & DECODE_FLAG_HAVE_TAG) - { - ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); - if (ret != ASN1_SUCCESS) - return ret; - - if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype)) - { - warn(); - return ASN1_DER_ERROR; - } - - p += tag_len; - der_len -= tag_len; - if (der_len <= 0) - return ASN1_DER_ERROR; - } - - ret = asn1_get_length_der (p, der_len, &len_len); - if (ret < 0) - return ASN1_DER_ERROR; - - p += len_len; - der_len -= len_len; - if (der_len <= 0) - return ASN1_DER_ERROR; - - *str_len = ret; - *str = p; - - return ASN1_SUCCESS; -} - -/** - * asn1_decode_simple_der: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * - * Decodes a simple DER encoded type (e.g. a string, which is not constructed). - * The output is a pointer inside the @der. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, const unsigned char **str, - unsigned int *str_len) -{ - return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG); -} - -static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size) -{ - if (src_size == 0) - return ASN1_SUCCESS; - - *dst = _asn1_realloc(*dst, *dst_size+src_size); - if (*dst == NULL) - return ASN1_MEM_ALLOC_ERROR; - memcpy(*dst + *dst_size, src, src_size); - *dst_size += src_size; - return ASN1_SUCCESS; -} - -/*- - * _asn1_decode_simple_ber: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @ber_len: the total length occupied by BER (may be %NULL) - * @have_tag: whether a DER tag is included - * - * Decodes a BER encoded type. The output is an allocated value - * of the data. This decodes BER STRINGS only. Other types are - * decoded as DER. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - -*/ -static int -_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len, - unsigned dflags) -{ - int tag_len, len_len; - const unsigned char *p; - int der_len = _der_len; - uint8_t *total = NULL; - unsigned total_size = 0; - unsigned char class; - unsigned long tag; - unsigned char *out = NULL; - const unsigned char *cout = NULL; - unsigned out_len; - long result; - - if (ber_len) *ber_len = 0; - - if (der == NULL || der_len == 0) - { - warn(); - return ASN1_VALUE_NOT_VALID; - } - - if (ETYPE_OK (etype) == 0) - { - warn(); - return ASN1_VALUE_NOT_VALID; - } - - /* doesn't handle constructed + definite classes */ - class = ETYPE_CLASS (etype); - if (class != ASN1_CLASS_UNIVERSAL) - { - warn(); - return ASN1_VALUE_NOT_VALID; - } - - p = der; - - if (dflags & DECODE_FLAG_HAVE_TAG) - { - result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); - if (result != ASN1_SUCCESS) - { - warn(); - return result; - } - - if (tag != ETYPE_TAG (etype)) - { - warn(); - return ASN1_DER_ERROR; - } - - p += tag_len; - - DECR_LEN(der_len, tag_len); - - if (ber_len) *ber_len += tag_len; - } - - /* indefinite constructed */ - if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype)) && - !(dflags & DECODE_FLAG_LEVEL3)) - { - if (der_len == 0) - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - - if (der_len > 0 && p[0] == 0x80) /* indefinite */ - { - len_len = 1; - DECR_LEN(der_len, len_len); - p += len_len; - - if (ber_len) *ber_len += len_len; - - /* decode the available octet strings */ - do - { - unsigned tmp_len; - unsigned flags = DECODE_FLAG_HAVE_TAG; - - if (dflags & DECODE_FLAG_LEVEL1) - flags |= DECODE_FLAG_LEVEL2; - else if (dflags & DECODE_FLAG_LEVEL2) - flags |= DECODE_FLAG_LEVEL3; - else - flags |= DECODE_FLAG_LEVEL1; - - result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, - flags); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - p += tmp_len; - DECR_LEN(der_len, tmp_len); - - if (ber_len) *ber_len += tmp_len; - - DECR_LEN(der_len, 2); /* we need the EOC */ - - result = append(&total, &total_size, out, out_len); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - free(out); - out = NULL; - - if (p[0] == 0 && p[1] == 0) /* EOC */ - { - if (ber_len) *ber_len += 2; - break; - } - - /* no EOC */ - der_len += 2; - - if (der_len == 2) - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - } - while(1); - } - else /* constructed */ - { - long const_len; - - result = asn1_get_length_ber(p, der_len, &len_len); - if (result < 0) - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - - DECR_LEN(der_len, len_len); - p += len_len; - - const_len = result; - - if (ber_len) *ber_len += len_len; - - /* decode the available octet strings */ - while(const_len > 0) - { - unsigned tmp_len; - unsigned flags = DECODE_FLAG_HAVE_TAG; - - if (dflags & DECODE_FLAG_LEVEL1) - flags |= DECODE_FLAG_LEVEL2; - else if (dflags & DECODE_FLAG_LEVEL2) - flags |= DECODE_FLAG_LEVEL3; - else - flags |= DECODE_FLAG_LEVEL1; - - result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, - flags); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - p += tmp_len; - DECR_LEN(der_len, tmp_len); - DECR_LEN(const_len, tmp_len); - - if (ber_len) *ber_len += tmp_len; - - result = append(&total, &total_size, out, out_len); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - free(out); - out = NULL; - } - } - } - else if (class == ETYPE_CLASS(etype)) - { - if (ber_len) - { - result = asn1_get_length_der (p, der_len, &len_len); - if (result < 0) - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - *ber_len += result + len_len; - } - - /* non-string values are decoded as DER */ - result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - - result = append(&total, &total_size, cout, out_len); - if (result != ASN1_SUCCESS) - { - warn(); - goto cleanup; - } - } - else - { - warn(); - result = ASN1_DER_ERROR; - goto cleanup; - } - - *str = total; - *str_len = total_size; - - return ASN1_SUCCESS; -cleanup: - free(out); - free(total); - return result; -} - -/** - * asn1_decode_simple_ber: - * @etype: The type of the string to be encoded (ASN1_ETYPE_) - * @der: the encoded string - * @_der_len: the bytes of the encoded string - * @str: a pointer to the data - * @str_len: the length of the data - * @ber_len: the total length occupied by BER (may be %NULL) - * - * Decodes a BER encoded type. The output is an allocated value - * of the data. This decodes BER STRINGS only. Other types are - * decoded as DER. - * - * Returns: %ASN1_SUCCESS if successful or an error value. - **/ -int -asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, unsigned char **str, - unsigned int *str_len, unsigned int *ber_len) -{ - return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG); -} diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c deleted file mode 100644 index 997eb27..0000000 --- a/lib/minitasn1/element.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* - * Copyright (C) 2000-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -/*****************************************************/ -/* File: element.c */ -/* Description: Functions with the read and write */ -/* functions. */ -/*****************************************************/ - - -#include -#include "parser_aux.h" -#include -#include "structure.h" -#include "c-ctype.h" -#include "element.h" - -void -_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size) -{ - asn1_node_const p; - char tmp_name[64]; - - p = node; - - name[0] = 0; - - while (p != NULL) - { - if (p->name[0] != 0) - { - _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), - _asn1_str_cpy (name, name_size, p->name); - _asn1_str_cat (name, name_size, "."); - _asn1_str_cat (name, name_size, tmp_name); - } - p = _asn1_find_up (p); - } - - if (name[0] == 0) - _asn1_str_cpy (name, name_size, "ROOT"); -} - - -/******************************************************************/ -/* Function : _asn1_convert_integer */ -/* Description: converts an integer from a null terminated string */ -/* to der decoding. The convertion from a null */ -/* terminated string to an integer is made with */ -/* the 'strtol' function. */ -/* Parameters: */ -/* value: null terminated string to convert. */ -/* value_out: convertion result (memory must be already */ -/* allocated). */ -/* value_out_size: number of bytes of value_out. */ -/* len: number of significant byte of value_out. */ -/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_convert_integer (const unsigned char *value, unsigned char *value_out, - int value_out_size, int *len) -{ - char negative; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - long valtmp; - int k, k2; - - valtmp = _asn1_strtol (value, NULL, 10); - - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - { - val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; - } - - if (val[0] & 0x80) - negative = 1; - else - negative = 0; - - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) - { - if (negative && (val[k] != 0xFF)) - break; - else if (!negative && val[k]) - break; - } - - if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) - k--; - - *len = SIZEOF_UNSIGNED_LONG_INT - k; - - if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) - /* VALUE_OUT is too short to contain the value conversion */ - return ASN1_MEM_ERROR; - - if (value_out != NULL) - { - for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) - value_out[k2 - k] = val[k2]; - } - -#if 0 - printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - printf (", vOut[%d]=%d", k, value_out[k]); - printf ("\n"); -#endif - - return ASN1_SUCCESS; -} - -/* Appends a new element into the sequence (or set) defined by this - * node. The new element will have a name of '?number', where number - * is a monotonically increased serial number. - * - * The last element in the list may be provided in @pcache, to avoid - * traversing the list, an expensive operation in long lists. - * - * On success it returns in @pcache the added element (which is the - * tail in the list of added elements). - */ -int -_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) -{ - asn1_node p, p2; - char temp[LTOSTR_MAX_SIZE]; - long n; - - if (!node || !(node->down)) - return ASN1_GENERIC_ERROR; - - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - - p2 = _asn1_copy_structure3 (p); - if (p2 == NULL) - return ASN1_GENERIC_ERROR; - - if (pcache == NULL || pcache->tail == NULL || pcache->head != node) - { - while (p->right) - { - p = p->right; - } - } - else - { - p = pcache->tail; - } - - _asn1_set_right (p, p2); - if (pcache) - { - pcache->head = node; - pcache->tail = p2; - } - - if (p->name[0] == 0) - _asn1_str_cpy (temp, sizeof (temp), "?1"); - else - { - n = strtol (p->name + 1, NULL, 0); - n++; - temp[0] = '?'; - _asn1_ltostr (n, temp + 1); - } - _asn1_set_name (p2, temp); - /* p2->type |= CONST_OPTION; */ - - return ASN1_SUCCESS; -} - - -/** - * asn1_write_value: - * @node_root: pointer to a structure - * @name: the name of the element inside the structure that you want to set. - * @ivalue: vector used to specify the value to set. If len is >0, - * VALUE must be a two's complement form integer. if len=0 *VALUE - * must be a null terminated string with an integer value. - * @len: number of bytes of *value to use to set the value: - * value[0]..value[len-1] or 0 if value is a null terminated string - * - * Set the value of one element inside a structure. - * - * If an element is OPTIONAL and you want to delete it, you must use - * the value=NULL and len=0. Using "pkix.asn": - * - * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID", - * NULL, 0); - * - * Description for each type: - * - * INTEGER: VALUE must contain a two's complement form integer. - * - * value[0]=0xFF , len=1 -> integer=-1. - * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1. - * value[0]=0x01 , len=1 -> integer= 1. - * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1. - * value="123" , len=0 -> integer= 123. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE must be the null terminated string "TRUE" or - * "FALSE" and LEN != 0. - * - * value="TRUE" , len=1 -> boolean=TRUE. - * value="FALSE" , len=1 -> boolean=FALSE. - * - * OBJECT IDENTIFIER: VALUE must be a null terminated string with - * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0. - * - * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha. - * - * UTCTime: VALUE must be a null terminated string in one of these - * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ", - * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'", - * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0. - * - * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 - * at 12h 00m Greenwich Mean Time - * - * GeneralizedTime: VALUE must be in one of this format: - * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ", - * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'", - * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s - * indicates the seconds with any precision like "10.1" or "01.02". - * LEN != 0 - * - * value="2001010112001.12-0700" , len=1 -> time=Jannuary - * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time - * - * OCTET STRING: VALUE contains the octet string and LEN is the - * number of octets. - * - * value="$\backslash$x01$\backslash$x02$\backslash$x03" , - * len=3 -> three bytes octet string - * - * GeneralString: VALUE contains the generalstring and LEN is the - * number of octets. - * - * value="$\backslash$x01$\backslash$x02$\backslash$x03" , - * len=3 -> three bytes generalstring - * - * BIT STRING: VALUE contains the bit string organized by bytes and - * LEN is the number of bits. - * - * value="$\backslash$xCF" , len=6 -> bit string="110011" (six - * bits) - * - * CHOICE: if NAME indicates a choice type, VALUE must specify one of - * the alternatives with a null terminated string. LEN != 0. Using - * "pkix.asn"\: - * - * result=asn1_write_value(cert, - * "certificate1.tbsCertificate.subject", "rdnSequence", - * 1); - * - * ANY: VALUE indicates the der encoding of a structure. LEN != 0. - * - * SEQUENCE OF: VALUE must be the null terminated string "NEW" and - * LEN != 0. With this instruction another element is appended in - * the sequence. The name of this element will be "?1" if it's the - * first one, "?2" for the second and so on. - * - * Using "pkix.asn"\: - * - * result=asn1_write_value(cert, - * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1); - * - * SET OF: the same as SEQUENCE OF. Using "pkix.asn": - * - * result=asn1_write_value(cert, - * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1); - * - * Returns: %ASN1_SUCCESS if the value was set, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and - * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format. - **/ -int -asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len) -{ - asn1_node node, p, p2; - unsigned char *temp, *value_temp = NULL, *default_temp = NULL; - int len2, k, k2, negative; - size_t i; - const unsigned char *value = ivalue; - unsigned int type; - - node = asn1_find_node (node_root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) - { - asn1_delete_structure (&node); - return ASN1_SUCCESS; - } - - type = type_field (node->type); - - if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0)) - { - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - - while (p->right) - asn1_delete_structure (&p->right); - - return ASN1_SUCCESS; - } - - /* Don't allow element deletion for other types */ - if (value == NULL) - { - return ASN1_VALUE_NOT_VALID; - } - - switch (type) - { - case ASN1_ETYPE_BOOLEAN: - if (!_asn1_strcmp (value, "TRUE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "T", 1); - } - else - _asn1_set_value (node, "T", 1); - } - else if (!_asn1_strcmp (value, "FALSE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_FALSE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "F", 1); - } - else - _asn1_set_value (node, "F", 1); - } - else - return ASN1_VALUE_NOT_VALID; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if (len == 0) - { - if ((c_isdigit (value[0])) || (value[0] == '-')) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (value, value_temp, - SIZEOF_UNSIGNED_LONG_INT, &len); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - return ASN1_VALUE_NOT_VALID; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p->name, value)) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (p->value, - value_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len); - break; - } - } - p = p->right; - } - if (p == NULL) - return ASN1_VALUE_NOT_VALID; - } - } - else - { /* len != 0 */ - value_temp = malloc (len); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - memcpy (value_temp, value, len); - } - - if (value_temp[0] & 0x80) - negative = 1; - else - negative = 0; - - if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - - for (k = 0; k < len - 1; k++) - if (negative && (value_temp[k] != 0xFF)) - break; - else if (!negative && value_temp[k]) - break; - - if ((negative && !(value_temp[k] & 0x80)) || - (!negative && (value_temp[k] & 0x80))) - k--; - - _asn1_set_value_lv (node, value_temp + k, len - k); - - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((c_isdigit (p->value[0])) || (p->value[0] == '-')) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; - } - - _asn1_convert_integer (p->value, default_temp, - SIZEOF_UNSIGNED_LONG_INT, &len2); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; - } - - _asn1_convert_integer (p2->value, - default_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len2); - break; - } - } - p2 = p2->right; - } - if (p2 == NULL) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } - } - - - if ((len - k) == len2) - { - for (k2 = 0; k2 < len2; k2++) - if (value_temp[k + k2] != default_temp[k2]) - { - break; - } - if (k2 == len2) - _asn1_set_value (node, NULL, 0); - } - free (default_temp); - } - free (value_temp); - break; - case ASN1_ETYPE_OBJECT_ID: - for (i = 0; i < _asn1_strlen (value); i++) - if ((!c_isdigit (value[i])) && (value[i] != '.') && (value[i] != '+')) - return ASN1_VALUE_NOT_VALID; - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (!_asn1_strcmp (value, p->value)) - { - _asn1_set_value (node, NULL, 0); - break; - } - } - _asn1_set_value (node, value, _asn1_strlen (value) + 1); - break; - case ASN1_ETYPE_UTC_TIME: - { - len = _asn1_strlen (value); - if (len < 11) - return ASN1_VALUE_NOT_VALID; - for (k = 0; k < 10; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - switch (len) - { - case 11: - if (value[10] != 'Z') - return ASN1_VALUE_NOT_VALID; - break; - case 13: - if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])) || - (value[12] != 'Z')) - return ASN1_VALUE_NOT_VALID; - break; - case 15: - if ((value[10] != '+') && (value[10] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 11; k < 15; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - case 17: - if ((!c_isdigit (value[10])) || (!c_isdigit (value[11]))) - return ASN1_VALUE_NOT_VALID; - if ((value[12] != '+') && (value[12] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 13; k < 17; k++) - if (!c_isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - default: - return ASN1_VALUE_NOT_FOUND; - } - _asn1_set_value (node, value, len); - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - len = _asn1_strlen (value); - _asn1_set_value (node, value, len); - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - if (len == 0) - len = _asn1_strlen (value); - _asn1_set_value_lv (node, value, len); - break; - case ASN1_ETYPE_BIT_STRING: - if (len == 0) - len = _asn1_strlen (value); - asn1_length_der ((len >> 3) + 2, NULL, &len2); - temp = malloc ((len >> 3) + 2 + len2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - asn1_bit_der (value, len, temp, &len2); - _asn1_set_value_m (node, temp, len2); - temp = NULL; - break; - case ASN1_ETYPE_CHOICE: - p = node->down; - while (p) - { - if (!_asn1_strcmp (p->name, value)) - { - p2 = node->down; - while (p2) - { - if (p2 != p) - { - asn1_delete_structure (&p2); - p2 = node->down; - } - else - p2 = p2->right; - } - break; - } - p = p->right; - } - if (!p) - return ASN1_ELEMENT_NOT_FOUND; - break; - case ASN1_ETYPE_ANY: - _asn1_set_value_lv (node, value, len); - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (_asn1_strcmp (value, "NEW")) - return ASN1_VALUE_NOT_VALID; - _asn1_append_sequence_set (node, NULL); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - - return ASN1_SUCCESS; -} - - -#define PUT_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size; \ - if (ptr_size < data_size) { \ - return ASN1_MEM_ERROR; \ - } else { \ - if (ptr && data_size > 0) \ - memcpy (ptr, data, data_size); \ - } - -#define PUT_STR_VALUE( ptr, ptr_size, data) \ - *len = _asn1_strlen (data) + 1; \ - if (ptr_size < *len) { \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcpy is checked */ \ - if (ptr) { \ - _asn1_strcpy (ptr, data); \ - } \ - } - -#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \ - *len = data_size + 1; \ - if (ptr_size < *len) { \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcpy is checked */ \ - if (ptr) { \ - if (data_size > 0) \ - memcpy (ptr, data, data_size); \ - ptr[data_size] = 0; \ - } \ - } - -#define ADD_STR_VALUE( ptr, ptr_size, data) \ - *len += _asn1_strlen(data); \ - if (ptr_size < (int) *len) { \ - (*len)++; \ - return ASN1_MEM_ERROR; \ - } else { \ - /* this strcat is checked */ \ - if (ptr) _asn1_strcat (ptr, data); \ - } - -/** - * asn1_read_value: - * @root: pointer to a structure. - * @name: the name of the element inside a structure that you want to read. - * @ivalue: vector that will contain the element's content, must be a - * pointer to memory cells already allocated (may be %NULL). - * @len: number of bytes of *value: value[0]..value[len-1]. Initialy - * holds the sizeof value. - * - * Returns the value of one element inside a structure. - * If an element is OPTIONAL and this returns - * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present - * in the der encoding that created the structure. The first element - * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and - * so on. If the @root provided is a node to specific sequence element, - * then the keyword "?CURRENT" is also acceptable and indicates the - * current sequence element of this node. - * - * Note that there can be valid values with length zero. In these case - * this function will succeed and @len will be zero. - * - * INTEGER: VALUE will contain a two's complement form integer. - * - * integer=-1 -> value[0]=0xFF , len=1. - * integer=1 -> value[0]=0x01 , len=1. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE will be the null terminated string "TRUE" or - * "FALSE" and LEN=5 or LEN=6. - * - * OBJECT IDENTIFIER: VALUE will be a null terminated string with - * each number separated by a dot (i.e. "1.2.3.543.1"). - * - * LEN = strlen(VALUE)+1 - * - * UTCTime: VALUE will be a null terminated string in one of these - * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". - * LEN=strlen(VALUE)+1. - * - * GeneralizedTime: VALUE will be a null terminated string in the - * same format used to set the value. - * - * OCTET STRING: VALUE will contain the octet string and LEN will be - * the number of octets. - * - * GeneralString: VALUE will contain the generalstring and LEN will - * be the number of octets. - * - * BIT STRING: VALUE will contain the bit string organized by bytes - * and LEN will be the number of bits. - * - * CHOICE: If NAME indicates a choice type, VALUE will specify the - * alternative selected. - * - * ANY: If NAME indicates an any type, VALUE will indicate the DER - * encoding of the structure actually used. - * - * Returns: %ASN1_SUCCESS if value is returned, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, - * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element - * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough - * to store the result, and in this case @len will contain the number of - * bytes needed. On the occasion that the stored data are of zero-length - * this function may return %ASN1_SUCCESS even if the provided @len is zero. - **/ -int -asn1_read_value (asn1_node_const root, const char *name, void *ivalue, int *len) -{ - return asn1_read_value_type (root, name, ivalue, len, NULL); -} - -/** - * asn1_read_value_type: - * @root: pointer to a structure. - * @name: the name of the element inside a structure that you want to read. - * @ivalue: vector that will contain the element's content, must be a - * pointer to memory cells already allocated (may be %NULL). - * @len: number of bytes of *value: value[0]..value[len-1]. Initialy - * holds the sizeof value. - * @etype: The type of the value read (ASN1_ETYPE) - * - * Returns the type and value of one element inside a structure. - * If an element is OPTIONAL and this returns - * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present - * in the der encoding that created the structure. The first element - * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and - * so on. If the @root provided is a node to specific sequence element, - * then the keyword "?CURRENT" is also acceptable and indicates the - * current sequence element of this node. - * - * Note that there can be valid values with length zero. In these case - * this function will succeed and @len will be zero. - * - * - * INTEGER: VALUE will contain a two's complement form integer. - * - * integer=-1 -> value[0]=0xFF , len=1. - * integer=1 -> value[0]=0x01 , len=1. - * - * ENUMERATED: As INTEGER (but only with not negative numbers). - * - * BOOLEAN: VALUE will be the null terminated string "TRUE" or - * "FALSE" and LEN=5 or LEN=6. - * - * OBJECT IDENTIFIER: VALUE will be a null terminated string with - * each number separated by a dot (i.e. "1.2.3.543.1"). - * - * LEN = strlen(VALUE)+1 - * - * UTCTime: VALUE will be a null terminated string in one of these - * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'". - * LEN=strlen(VALUE)+1. - * - * GeneralizedTime: VALUE will be a null terminated string in the - * same format used to set the value. - * - * OCTET STRING: VALUE will contain the octet string and LEN will be - * the number of octets. - * - * GeneralString: VALUE will contain the generalstring and LEN will - * be the number of octets. - * - * BIT STRING: VALUE will contain the bit string organized by bytes - * and LEN will be the number of bits. - * - * CHOICE: If NAME indicates a choice type, VALUE will specify the - * alternative selected. - * - * ANY: If NAME indicates an any type, VALUE will indicate the DER - * encoding of the structure actually used. - * - * Returns: %ASN1_SUCCESS if value is returned, - * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, - * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element - * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough - * to store the result, and in this case @len will contain the number of - * bytes needed. On the occasion that the stored data are of zero-length - * this function may return %ASN1_SUCCESS even if the provided @len is zero. - **/ -int -asn1_read_value_type (asn1_node_const root, const char *name, void *ivalue, - int *len, unsigned int *etype) -{ - asn1_node_const node, p, p2; - int len2, len3, result; - int value_size = *len; - unsigned char *value = ivalue; - unsigned type; - - node = asn1_find_node (root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - type = type_field (node->type); - - if ((type != ASN1_ETYPE_NULL) && - (type != ASN1_ETYPE_CHOICE) && - !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) && - (node->value == NULL)) - return ASN1_VALUE_NOT_FOUND; - - if (etype) - *etype = type; - switch (type) - { - case ASN1_ETYPE_NULL: - PUT_STR_VALUE (value, value_size, "NULL"); - break; - case ASN1_ETYPE_BOOLEAN: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - } - else if (node->value[0] == 'T') - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((c_isdigit (p->value[0])) || (p->value[0] == '-') - || (p->value[0] == '+')) - { - result = _asn1_convert_integer - (p->value, value, value_size, len); - if (result != ASN1_SUCCESS) - return result; - } - else - { /* is an identifier like v1 */ - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - result = _asn1_convert_integer - (p2->value, value, value_size, - len); - if (result != ASN1_SUCCESS) - return result; - break; - } - } - p2 = p2->right; - } - } - } - else - { - len2 = -1; - result = asn1_get_octet_der - (node->value, node->value_len, &len2, value, value_size, - len); - if (result != ASN1_SUCCESS) - return result; - } - break; - case ASN1_ETYPE_OBJECT_ID: - if (node->type & CONST_ASSIGN) - { - *len = 0; - if (value) - value[0] = 0; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - ADD_STR_VALUE (value, value_size, p->value); - if (p->right) - { - ADD_STR_VALUE (value, value_size, "."); - } - } - p = p->right; - } - (*len)++; - } - else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - PUT_STR_VALUE (value, value_size, p->value); - } - else - { - PUT_STR_VALUE (value, value_size, node->value); - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len); - break; - case ASN1_ETYPE_OCTET_STRING: - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - len2 = -1; - result = asn1_get_octet_der - (node->value, node->value_len, &len2, value, value_size, - len); - if (result != ASN1_SUCCESS) - return result; - break; - case ASN1_ETYPE_BIT_STRING: - len2 = -1; - result = asn1_get_bit_der - (node->value, node->value_len, &len2, value, value_size, - len); - if (result != ASN1_SUCCESS) - return result; - break; - case ASN1_ETYPE_CHOICE: - PUT_STR_VALUE (value, value_size, node->down->name); - break; - case ASN1_ETYPE_ANY: - len3 = -1; - len2 = asn1_get_length_der (node->value, node->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - PUT_VALUE (value, value_size, node->value + len3, len2); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - return ASN1_SUCCESS; -} - - -/** - * asn1_read_tag: - * @root: pointer to a structure - * @name: the name of the element inside a structure. - * @tagValue: variable that will contain the TAG value. - * @classValue: variable that will specify the TAG type. - * - * Returns the TAG and the CLASS of one element inside a structure. - * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION, - * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or - * %ASN1_CLASS_CONTEXT_SPECIFIC. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * @name is not a valid element. - **/ -int -asn1_read_tag (asn1_node_const root, const char *name, int *tagValue, - int *classValue) -{ - asn1_node node, p, pTag; - - node = asn1_find_node (root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node->down; - - /* pTag will points to the IMPLICIT TAG */ - pTag = NULL; - if (node->type & CONST_TAG) - { - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) - pTag = p; - else if (p->type & CONST_EXPLICIT) - pTag = NULL; - } - p = p->right; - } - } - - if (pTag) - { - *tagValue = _asn1_strtoul (pTag->value, NULL, 10); - - if (pTag->type & CONST_APPLICATION) - *classValue = ASN1_CLASS_APPLICATION; - else if (pTag->type & CONST_UNIVERSAL) - *classValue = ASN1_CLASS_UNIVERSAL; - else if (pTag->type & CONST_PRIVATE) - *classValue = ASN1_CLASS_PRIVATE; - else - *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; - } - else - { - unsigned type = type_field (node->type); - *classValue = ASN1_CLASS_UNIVERSAL; - - switch (type) - { - CASE_HANDLED_ETYPES: - *tagValue = _asn1_tags[type].tag; - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - *tagValue = -1; - break; - default: - break; - } - } - - return ASN1_SUCCESS; -} - -/** - * asn1_read_node_value: - * @node: pointer to a node. - * @data: a point to a asn1_data_node_st - * - * Returns the value a data node inside a asn1_node structure. - * The data returned should be handled as constant values. - * - * Returns: %ASN1_SUCCESS if the node exists. - **/ -int -asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data) -{ - data->name = node->name; - data->value = node->value; - data->value_len = node->value_len; - data->type = type_field (node->type); - - return ASN1_SUCCESS; -} diff --git a/lib/minitasn1/element.h b/lib/minitasn1/element.h deleted file mode 100644 index 440a33f..0000000 --- a/lib/minitasn1/element.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2000-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifndef _ELEMENT_H -#define _ELEMENT_H - - -struct node_tail_cache_st -{ - asn1_node head; /* the first element of the sequence */ - asn1_node tail; -}; - -int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached); - -int _asn1_convert_integer (const unsigned char *value, - unsigned char *value_out, - int value_out_size, int *len); - -void _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size); - -#endif diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c deleted file mode 100644 index cee74da..0000000 --- a/lib/minitasn1/errors.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#include -#ifdef STDC_HEADERS -#include -#endif - -#define LIBTASN1_ERROR_ENTRY(name) { #name, name } - -struct libtasn1_error_entry -{ - const char *name; - int number; -}; -typedef struct libtasn1_error_entry libtasn1_error_entry; - -static const libtasn1_error_entry error_algorithms[] = { - LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), - LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), - LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), - LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), - LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), - LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), - LIBTASN1_ERROR_ENTRY (ASN1_TIME_ENCODING_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_RECURSION), - {0, 0} -}; - -/** - * asn1_perror: - * @error: is an error returned by a libtasn1 function. - * - * Prints a string to stderr with a description of an error. This - * function is like perror(). The only difference is that it accepts - * an error returned by a libtasn1 function. - * - * Since: 1.6 - **/ -void -asn1_perror (int error) -{ - const char *str = asn1_strerror (error); - fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); -} - -/** - * asn1_strerror: - * @error: is an error returned by a libtasn1 function. - * - * Returns a string with a description of an error. This function is - * similar to strerror. The only difference is that it accepts an - * error (number) returned by a libtasn1 function. - * - * Returns: Pointer to static zero-terminated string describing error - * code. - * - * Since: 1.6 - **/ -const char * -asn1_strerror (int error) -{ - const libtasn1_error_entry *p; - - for (p = error_algorithms; p->name != NULL; p++) - if (p->number == error) - return p->name + sizeof ("ASN1_") - 1; - - return NULL; -} diff --git a/lib/minitasn1/gstr.c b/lib/minitasn1/gstr.c deleted file mode 100644 index e91a3a1..0000000 --- a/lib/minitasn1/gstr.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#include -#include "gstr.h" - -/* These function are like strcat, strcpy. They only - * do bounds checking (they shouldn't cause buffer overruns), - * and they always produce null terminated strings. - * - * They should be used only with null terminated strings. - */ -void -_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) -{ - size_t str_size = strlen (src); - size_t dest_size = strlen (dest); - - if (dest_tot_size - dest_size > str_size) - { - strcat (dest, src); - } - else - { - if (dest_tot_size - dest_size > 0) - { - strncat (dest, src, (dest_tot_size - dest_size) - 1); - dest[dest_tot_size - 1] = 0; - } - } -} - -/* Returns the bytes copied (not including the null terminator) */ -unsigned int -_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) -{ - size_t str_size = strlen (src); - - if (dest_tot_size > str_size) - { - strcpy (dest, src); - return str_size; - } - else - { - if (dest_tot_size > 0) - { - str_size = dest_tot_size - 1; - memcpy (dest, src, str_size); - dest[str_size] = 0; - return str_size; - } - else - return 0; - } -} diff --git a/lib/minitasn1/gstr.h b/lib/minitasn1/gstr.h deleted file mode 100644 index 4822984..0000000 --- a/lib/minitasn1/gstr.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifndef GSTR_H -# define GSTR_H - -unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, - const char *src); -void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); - -#define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) -#define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) - -inline static -void safe_memset(void *data, int c, size_t size) -{ - volatile unsigned volatile_zero = 0; - volatile char *vdata = (volatile char*)data; - - /* This is based on a nice trick for safe memset, - * sent by David Jacobson in the openssl-dev mailing list. - */ - - if (size > 0) do { - memset(data, c, size); - } while(vdata[volatile_zero] != c); -} - -#endif /* GSTR_H */ diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h deleted file mode 100644 index ea16257..0000000 --- a/lib/minitasn1/int.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifndef INT_H -#define INT_H - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include - -#define ASN1_SMALL_VALUE_SIZE 16 - -/* This structure is also in libtasn1.h, but then contains less - fields. You cannot make any modifications to these first fields - without breaking ABI. */ -struct asn1_node_st -{ - /* public fields: */ - char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ - unsigned int name_hash; - unsigned int type; /* Node type */ - unsigned char *value; /* Node value */ - int value_len; - asn1_node down; /* Pointer to the son node */ - asn1_node right; /* Pointer to the brother node */ - asn1_node left; /* Pointer to the next list element */ - /* private fields: */ - unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ - - /* values used during decoding/coding */ - int tmp_ival; - unsigned start; /* the start of the DER sequence - if decoded */ - unsigned end; /* the end of the DER sequence - if decoded */ -}; - -typedef struct tag_and_class_st -{ - unsigned tag; - unsigned class; - const char *desc; -} tag_and_class_st; - -/* the types that are handled in _asn1_tags */ -#define CASE_HANDLED_ETYPES \ - case ASN1_ETYPE_NULL: \ - case ASN1_ETYPE_BOOLEAN: \ - case ASN1_ETYPE_INTEGER: \ - case ASN1_ETYPE_ENUMERATED: \ - case ASN1_ETYPE_OBJECT_ID: \ - case ASN1_ETYPE_OCTET_STRING: \ - case ASN1_ETYPE_GENERALSTRING: \ - case ASN1_ETYPE_NUMERIC_STRING: \ - case ASN1_ETYPE_IA5_STRING: \ - case ASN1_ETYPE_TELETEX_STRING: \ - case ASN1_ETYPE_PRINTABLE_STRING: \ - case ASN1_ETYPE_UNIVERSAL_STRING: \ - case ASN1_ETYPE_BMP_STRING: \ - case ASN1_ETYPE_UTF8_STRING: \ - case ASN1_ETYPE_VISIBLE_STRING: \ - case ASN1_ETYPE_BIT_STRING: \ - case ASN1_ETYPE_SEQUENCE: \ - case ASN1_ETYPE_SEQUENCE_OF: \ - case ASN1_ETYPE_SET: \ - case ASN1_ETYPE_UTC_TIME: \ - case ASN1_ETYPE_GENERALIZED_TIME: \ - case ASN1_ETYPE_SET_OF - -#define ETYPE_TAG(etype) (_asn1_tags[etype].tag) -#define ETYPE_CLASS(etype) (_asn1_tags[etype].class) -#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ - (etype) <= _asn1_tags_size && \ - _asn1_tags[(etype)].desc != NULL)?1:0) - -#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ - etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \ - etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \ - etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \ - etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \ - etype == ASN1_ETYPE_OCTET_STRING)?1:0) - -extern unsigned int _asn1_tags_size; -extern const tag_and_class_st _asn1_tags[]; - -#define _asn1_strlen(s) strlen((const char *) s) -#define _asn1_strtol(n,e,b) strtol((const char *) n, e, b) -#define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) -#define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) -#define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) -#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) - -#if SIZEOF_UNSIGNED_LONG_INT == 8 -# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) -#else -# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b) -#endif - -#define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ - -/* Define used for visiting trees. */ -#define UP 1 -#define RIGHT 2 -#define DOWN 3 - -/***********************************************************************/ -/* List of constants to better specify the type of typedef asn1_node_st. */ -/***********************************************************************/ -/* Used with TYPE_TAG */ -#define CONST_UNIVERSAL (1U<<8) -#define CONST_PRIVATE (1U<<9) -#define CONST_APPLICATION (1U<<10) -#define CONST_EXPLICIT (1U<<11) -#define CONST_IMPLICIT (1U<<12) - -#define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */ -#define CONST_OPTION (1U<<14) -#define CONST_DEFAULT (1U<<15) -#define CONST_TRUE (1U<<16) -#define CONST_FALSE (1U<<17) - -#define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ -#define CONST_MIN_MAX (1U<<19) - -#define CONST_1_PARAM (1U<<20) - -#define CONST_SIZE (1U<<21) - -#define CONST_DEFINED_BY (1U<<22) - -/* Those two are deprecated and used for backwards compatibility */ -#define CONST_GENERALIZED (1U<<23) -#define CONST_UTC (1U<<24) - -/* #define CONST_IMPORTS (1U<<25) */ - -#define CONST_NOT_USED (1U<<26) -#define CONST_SET (1U<<27) -#define CONST_ASSIGN (1U<<28) - -#define CONST_DOWN (1U<<29) -#define CONST_RIGHT (1U<<30) - - -#define ASN1_ETYPE_TIME 17 -/****************************************/ -/* Returns the first 8 bits. */ -/* Used with the field type of asn1_node_st */ -/****************************************/ -inline static unsigned int -type_field (unsigned int ntype) -{ - return (ntype & 0xff); -} - -/* To convert old types from a static structure */ -inline static unsigned int -convert_old_type (unsigned int ntype) -{ - unsigned int type = ntype & 0xff; - if (type == ASN1_ETYPE_TIME) - { - if (ntype & CONST_UTC) - type = ASN1_ETYPE_UTC_TIME; - else - type = ASN1_ETYPE_GENERALIZED_TIME; - - ntype &= ~(CONST_UTC | CONST_GENERALIZED); - ntype &= 0xffffff00; - ntype |= type; - - return ntype; - } - else - return ntype; -} - -static inline -void *_asn1_realloc(void *ptr, size_t size) -{ - void *ret; - - if (size == 0) - return ptr; - - ret = realloc(ptr, size); - if (ret == NULL) - { - free(ptr); - } - return ret; -} - -#endif /* INT_H */ diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h deleted file mode 100644 index 6fd7a30..0000000 --- a/lib/minitasn1/libtasn1.h +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * LIBTASN1 is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * LIBTASN1 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with LIBTASN1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -/** - * libtasn1:Short_Description: - * - * GNU ASN.1 library - */ -/** - * libtasn1:Long_Description: - * - * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as - * specified by the X.680 ITU-T recommendation) parsing and structures - * management, and Distinguished Encoding Rules (DER, as per X.690) - * encoding and decoding functions. - */ - - -#ifndef LIBTASN1_H -#define LIBTASN1_H - -#ifndef ASN1_API -#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY -#define ASN1_API __attribute__((__visibility__("default"))) -#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC -#define ASN1_API __declspec(dllexport) -#elif defined _MSC_VER && ! defined ASN1_STATIC -#define ASN1_API __declspec(dllimport) -#else -#define ASN1_API -#endif -#endif - -#ifdef __GNUC__ -# define __LIBTASN1_CONST__ __attribute__((const)) -# define __LIBTASN1_PURE__ __attribute__((pure)) -#else -# define __LIBTASN1_CONST__ -# define __LIBTASN1_PURE__ -#endif - -#include -#include -#include /* for FILE* */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * ASN1_VERSION: - * - * Version of the library as a string. - */ -#define ASN1_VERSION "4.16.0" - -/** - * ASN1_VERSION_MAJOR: - * - * Major version number of the library. - */ -#define ASN1_VERSION_MAJOR 4 - -/** - * ASN1_VERSION_MINOR: - * - * Minor version number of the library. - */ -#define ASN1_VERSION_MINOR 16 - -/** - * ASN1_VERSION_PATCH: - * - * Patch version number of the library. - */ -#define ASN1_VERSION_PATCH 0 - -/** - * ASN1_VERSION_NUMBER: - * - * Version number of the library as a number. - */ -#define ASN1_VERSION_NUMBER 0x041000 - - -#if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD -# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -# if _ASN1_GCC_VERSION >= 30100 -# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) -# endif -#endif - -#ifndef _ASN1_GCC_ATTR_DEPRECATED -#define _ASN1_GCC_ATTR_DEPRECATED -#endif - -/*****************************************/ -/* Errors returned by libtasn1 functions */ -/*****************************************/ -#define ASN1_SUCCESS 0 -#define ASN1_FILE_NOT_FOUND 1 -#define ASN1_ELEMENT_NOT_FOUND 2 -#define ASN1_IDENTIFIER_NOT_FOUND 3 -#define ASN1_DER_ERROR 4 -#define ASN1_VALUE_NOT_FOUND 5 -#define ASN1_GENERIC_ERROR 6 -#define ASN1_VALUE_NOT_VALID 7 -#define ASN1_TAG_ERROR 8 -#define ASN1_TAG_IMPLICIT 9 -#define ASN1_ERROR_TYPE_ANY 10 -#define ASN1_SYNTAX_ERROR 11 -#define ASN1_MEM_ERROR 12 -#define ASN1_MEM_ALLOC_ERROR 13 -#define ASN1_DER_OVERFLOW 14 -#define ASN1_NAME_TOO_LONG 15 -#define ASN1_ARRAY_ERROR 16 -#define ASN1_ELEMENT_NOT_EMPTY 17 -#define ASN1_TIME_ENCODING_ERROR 18 -#define ASN1_RECURSION 19 - -/*************************************/ -/* Constants used in asn1_visit_tree */ -/*************************************/ -#define ASN1_PRINT_NAME 1 -#define ASN1_PRINT_NAME_TYPE 2 -#define ASN1_PRINT_NAME_TYPE_VALUE 3 -#define ASN1_PRINT_ALL 4 - -/*****************************************/ -/* Constants returned by asn1_read_tag */ -/*****************************************/ -#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ -#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ -#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ -#define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ -#define ASN1_CLASS_STRUCTURED 0x20 - -/*****************************************/ -/* Constants returned by asn1_read_tag */ -/*****************************************/ -#define ASN1_TAG_BOOLEAN 0x01 -#define ASN1_TAG_INTEGER 0x02 -#define ASN1_TAG_SEQUENCE 0x10 -#define ASN1_TAG_SET 0x11 -#define ASN1_TAG_OCTET_STRING 0x04 -#define ASN1_TAG_BIT_STRING 0x03 -#define ASN1_TAG_UTCTime 0x17 -#define ASN1_TAG_GENERALIZEDTime 0x18 -#define ASN1_TAG_OBJECT_ID 0x06 -#define ASN1_TAG_ENUMERATED 0x0A -#define ASN1_TAG_NULL 0x05 -#define ASN1_TAG_GENERALSTRING 0x1B -#define ASN1_TAG_NUMERIC_STRING 0x12 -#define ASN1_TAG_IA5_STRING 0x16 -#define ASN1_TAG_TELETEX_STRING 0x14 -#define ASN1_TAG_PRINTABLE_STRING 0x13 -#define ASN1_TAG_UNIVERSAL_STRING 0x1C -#define ASN1_TAG_BMP_STRING 0x1E -#define ASN1_TAG_UTF8_STRING 0x0C -#define ASN1_TAG_VISIBLE_STRING 0x1A - -/** - * asn1_node: - * - * Structure definition used for the node of the tree - * that represents an ASN.1 DEFINITION. - */ -typedef struct asn1_node_st asn1_node_st; - -typedef asn1_node_st *asn1_node; -typedef const asn1_node_st *asn1_node_const; - -/** - * ASN1_MAX_NAME_SIZE: - * - * Maximum number of characters of a name - * inside a file with ASN1 definitions. - */ -#define ASN1_MAX_NAME_SIZE 64 - - -/** - * asn1_static_node: - * @name: Node name - * @type: Node typ - * @value: Node value - * - * For the on-disk format of ASN.1 trees, created by asn1_parser2array(). - */ -struct asn1_static_node_st -{ - const char *name; /* Node name */ - unsigned int type; /* Node type */ - const void *value; /* Node value */ -}; -typedef struct asn1_static_node_st asn1_static_node; - -/* List of constants for field type of node_asn */ -#define ASN1_ETYPE_INVALID 0 -#define ASN1_ETYPE_CONSTANT 1 -#define ASN1_ETYPE_IDENTIFIER 2 -#define ASN1_ETYPE_INTEGER 3 -#define ASN1_ETYPE_BOOLEAN 4 -#define ASN1_ETYPE_SEQUENCE 5 -#define ASN1_ETYPE_BIT_STRING 6 -#define ASN1_ETYPE_OCTET_STRING 7 -#define ASN1_ETYPE_TAG 8 -#define ASN1_ETYPE_DEFAULT 9 -#define ASN1_ETYPE_SIZE 10 -#define ASN1_ETYPE_SEQUENCE_OF 11 -#define ASN1_ETYPE_OBJECT_ID 12 -#define ASN1_ETYPE_ANY 13 -#define ASN1_ETYPE_SET 14 -#define ASN1_ETYPE_SET_OF 15 -#define ASN1_ETYPE_DEFINITIONS 16 -#define ASN1_ETYPE_CHOICE 18 -#define ASN1_ETYPE_IMPORTS 19 -#define ASN1_ETYPE_NULL 20 -#define ASN1_ETYPE_ENUMERATED 21 -#define ASN1_ETYPE_GENERALSTRING 27 -#define ASN1_ETYPE_NUMERIC_STRING 28 -#define ASN1_ETYPE_IA5_STRING 29 -#define ASN1_ETYPE_TELETEX_STRING 30 -#define ASN1_ETYPE_PRINTABLE_STRING 31 -#define ASN1_ETYPE_UNIVERSAL_STRING 32 -#define ASN1_ETYPE_BMP_STRING 33 -#define ASN1_ETYPE_UTF8_STRING 34 -#define ASN1_ETYPE_VISIBLE_STRING 35 -#define ASN1_ETYPE_UTC_TIME 36 -#define ASN1_ETYPE_GENERALIZED_TIME 37 - -/** - * ASN1_DELETE_FLAG_ZEROIZE: - * - * Used by: asn1_delete_structure2() - * - * Zeroize values prior to deinitialization. - */ -#define ASN1_DELETE_FLAG_ZEROIZE 1 - -/** - * ASN1_DECODE_FLAG_ALLOW_PADDING: - * - * Used by: asn1_der_decoding2() - * - * This flag would allow arbitrary data past the DER data. - */ -#define ASN1_DECODE_FLAG_ALLOW_PADDING 1 -/** - * ASN1_DECODE_FLAG_STRICT_DER: - * - * Used by: asn1_der_decoding2() - * - * This flag would ensure that no BER decoding takes place. - */ -#define ASN1_DECODE_FLAG_STRICT_DER (1<<1) -/** - * ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME: - * - * Used by: asn1_der_decoding2() - * - * This flag will tolerate Time encoding errors when in strict DER. - */ -#define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2) - - -/** - * asn1_data_node_st: - * @name: Node name - * @value: Node value - * @value_len: Node value size - * @type: Node value type (ASN1_ETYPE_*) - * - * Data node inside a #asn1_node structure. - */ -struct asn1_data_node_st -{ - const char *name; /* Node name */ - const void *value; /* Node value */ - unsigned int value_len; /* Node value size */ - unsigned int type; /* Node value type (ASN1_ETYPE_*) */ -}; -typedef struct asn1_data_node_st asn1_data_node_st; - -/***********************************/ -/* Fixed constants */ -/***********************************/ - -/** - * ASN1_MAX_ERROR_DESCRIPTION_SIZE: - * - * Maximum number of characters - * of a description message - * (null character included). - */ -#define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 - -/***********************************/ -/* Functions definitions */ -/***********************************/ - -extern ASN1_API int - asn1_parser2tree (const char *file, - asn1_node * definitions, char *error_desc); - -extern ASN1_API int - asn1_parser2array (const char *inputFileName, - const char *outputFileName, - const char *vectorName, char *error_desc); - -extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, - asn1_node * definitions, char *errorDescription); - -extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node_const structure, - const char *name, int mode); - -extern ASN1_API int - asn1_create_element (asn1_node_const definitions, - const char *source_name, asn1_node * element); - -extern ASN1_API int asn1_delete_structure (asn1_node * structure); - -extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int flags); - -extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); - -extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len); - -extern ASN1_API int - asn1_read_value (asn1_node_const root, const char *name, - void *ivalue, int *len); - -extern ASN1_API int - asn1_read_value_type (asn1_node_const root, const char *name, - void *ivalue, int *len, unsigned int *etype); - -extern ASN1_API int - asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data); - -extern ASN1_API int - asn1_number_of_elements (asn1_node_const element, const char *name, int *num); - -extern ASN1_API int - asn1_der_coding (asn1_node_const element, const char *name, - void *ider, int *len, char *ErrorDescription); - -extern ASN1_API int - asn1_der_decoding2 (asn1_node *element, const void *ider, - int *max_ider_len, unsigned int flags, - char *errorDescription); - -extern ASN1_API int - asn1_der_decoding (asn1_node * element, const void *ider, - int ider_len, char *errorDescription); - -/* Do not use. Use asn1_der_decoding() instead. */ -extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, - const char *elementName, - const void *ider, int len, - char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED; - -extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, - const void *ider, int ider_len, - const char *name_element, - int *start, int *end); - -extern ASN1_API int - asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element); - -extern ASN1_API int - asn1_expand_octet_string (asn1_node_const definitions, - asn1_node * element, - const char *octetName, const char *objectName); - -extern ASN1_API int - asn1_read_tag (asn1_node_const root, const char *name, - int *tagValue, int *classValue); - -extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const - definitions, - const char - *oidValue); - -__LIBTASN1_PURE__ -extern ASN1_API const char *asn1_check_version (const char *req_version); - -__LIBTASN1_PURE__ -extern ASN1_API const char *asn1_strerror (int error); - -extern ASN1_API void asn1_perror (int error); - -#define ASN1_MAX_TAG_SIZE 4 -#define ASN1_MAX_LENGTH_SIZE 9 -#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE) -extern ASN1_API long - asn1_get_length_der (const unsigned char *der, int der_len, int *len); - -extern ASN1_API long - asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len); - -extern ASN1_API void - asn1_length_der (unsigned long int len, unsigned char *der, int *der_len); - -/* Other utility functions. */ - -extern ASN1_API - int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, - unsigned int _der_len, - const unsigned char **str, - unsigned int *str_len); - -extern ASN1_API - int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, - unsigned int _der_len, - unsigned char **str, - unsigned int *str_len, - unsigned int *ber_len); - -extern ASN1_API int - asn1_encode_simple_der (unsigned int etype, const unsigned char *str, - unsigned int str_len, unsigned char *tl, - unsigned int *tl_len); - -extern ASN1_API asn1_node - asn1_find_node (asn1_node_const pointer, const char *name); - -extern ASN1_API int - asn1_copy_node (asn1_node dst, const char *dst_name, - asn1_node_const src, const char *src_name); -extern ASN1_API asn1_node - asn1_dup_node (asn1_node_const src, const char *src_name); - -/* Internal and low-level DER utility functions. */ - -extern ASN1_API int - asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag); - -extern ASN1_API void - asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len); - -extern ASN1_API int - asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *str_len); - -extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len); - -extern ASN1_API int - asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *bit_len); - -extern ASN1_API int - asn1_get_object_id_der (const unsigned char *der, - int der_len, int *ret_len, - char *str, int str_size); - -extern ASN1_API int - asn1_object_id_der (const char *str, unsigned char *der, int *der_len, - unsigned flags); - -/* Compatibility types */ - -/** - * asn1_retCode: - * - * Type formerly returned by libtasn1 functions. - * - * Deprecated: 3.0: Use int instead. - */ -typedef int asn1_retCode; - -/** - * node_asn_struct: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -#define node_asn_struct asn1_node_st - -/** - * node_asn: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -#define node_asn asn1_node_st - -/** - * ASN1_TYPE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_node instead. - */ -#define ASN1_TYPE asn1_node - -/** - * ASN1_TYPE_EMPTY: - * - * Compat #define. - * - * Deprecated: 3.0: Use NULL instead. - */ -#define ASN1_TYPE_EMPTY NULL - -/** - * static_struct_asn: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -#define static_struct_asn asn1_static_node_st - -/** - * ASN1_ARRAY_TYPE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -#define ASN1_ARRAY_TYPE asn1_static_node - -/** - * asn1_static_node_t: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_static_node instead. - */ -#define asn1_static_node_t asn1_static_node - -/** - * node_data_struct: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_data_node_st instead. - */ -#define node_data_struct asn1_data_node_st - -/** - * ASN1_DATA_NODE: - * - * Compat #define. - * - * Deprecated: 3.0: Use #asn1_data_node_st instead. - */ -#define ASN1_DATA_NODE asn1_data_node_st - -#ifdef __cplusplus -} -#endif - -#endif /* LIBTASN1_H */ diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c deleted file mode 100644 index d5dbbf8..0000000 --- a/lib/minitasn1/parser_aux.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* - * Copyright (C) 2000-2016 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#include // WORD_BIT - -#include "int.h" -#include "parser_aux.h" -#include "gstr.h" -#include "structure.h" -#include "element.h" -#include "c-ctype.h" - -char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ - -/* Return a hash of the N bytes of X using the method described by - Bruno Haible in https://www.haible.de/bruno/hashfunc.html. - Note that while many hash functions reduce their result via modulo - to a 0..table_size-1 range, this function does not do that. - - This implementation has been changed from size_t -> unsigned int. */ - -#ifdef __clang__ -__attribute__((no_sanitize("integer"))) -#endif -_GL_ATTRIBUTE_PURE -static unsigned int -_asn1_hash_name (const char *x) -{ - const unsigned char *s = (unsigned char *) x; - unsigned h = 0; - - while (*s) - h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9))); - - return h; -} - -/******************************************************/ -/* Function : _asn1_add_static_node */ -/* Description: creates a new NODE_ASN element and */ -/* puts it in the list pointed by e_list. */ -/* Parameters: */ -/* e_list: of type list_type; must be NULL initially */ -/* type: type of the new element (see ASN1_ETYPE_ */ -/* and CONST_ constants). */ -/* Return: pointer to the new element. */ -/******************************************************/ -asn1_node -_asn1_add_static_node (list_type **e_list, unsigned int type) -{ - list_type *p; - asn1_node punt; - - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; - - p = malloc (sizeof (list_type)); - if (p == NULL) - { - free (punt); - return NULL; - } - - p->node = punt; - p->next = *e_list; - *e_list = p; - - punt->type = type; - - return punt; -} - -static -int _asn1_add_static_node2 (list_type **e_list, asn1_node node) -{ - list_type *p; - - p = malloc (sizeof (list_type)); - if (p == NULL) - { - return -1; - } - - p->node = node; - p->next = *e_list; - *e_list = p; - - return 0; -} - -/** - * asn1_find_node: - * @pointer: NODE_ASN element pointer. - * @name: null terminated string with the element's name to find. - * - * Searches for an element called @name starting from @pointer. The - * name is composed by different identifiers separated by dots. When - * *@pointer has a name, the first identifier must be the name of - * *@pointer, otherwise it must be the name of one child of *@pointer. - * - * Returns: the search result, or %NULL if not found. - **/ -asn1_node -asn1_find_node (asn1_node_const pointer, const char *name) -{ - asn1_node_const p; - char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; - const char *n_start; - unsigned int nsize; - unsigned int nhash; - - if (pointer == NULL) - return NULL; - - if (name == NULL) - return NULL; - - p = pointer; - n_start = name; - - if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?') - { /* ?CURRENT */ - n_start = strchr(n_start, '.'); - if (n_start) - n_start++; - } - else if (p->name[0] != 0) - { /* has *pointer got a name ? */ - n_end = strchr (n_start, '.'); /* search the first dot */ - if (n_end) - { - nsize = n_end - n_start; - if (nsize >= sizeof(n)) - return NULL; - - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = _asn1_hash_name (n); - } - else - { - _asn1_str_cpy (n, sizeof (n), n_start); - nhash = _asn1_hash_name (n); - - n_start = NULL; - } - - while (p) - { - if (nhash == p->name_hash && (!strcmp (p->name, n))) - break; - else - p = p->right; - } /* while */ - - if (p == NULL) - return NULL; - } - else - { /* *pointer doesn't have a name */ - if (n_start[0] == 0) - return (asn1_node) p; - } - - while (n_start) - { /* Has the end of NAME been reached? */ - n_end = strchr (n_start, '.'); /* search the next dot */ - if (n_end) - { - nsize = n_end - n_start; - if (nsize >= sizeof(n)) - return NULL; - - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = _asn1_hash_name (n); - } - else - { - _asn1_str_cpy (n, sizeof (n), n_start); - nhash = _asn1_hash_name (n); - n_start = NULL; - } - - if (p->down == NULL) - return NULL; - - p = p->down; - if (p == NULL) - return NULL; - - /* The identifier "?LAST" indicates the last element - in the right chain. */ - if (n[0] == '?' && n[1] == 'L') /* ?LAST */ - { - while (p->right) - p = p->right; - } - else - { /* no "?LAST" */ - while (p) - { - if (p->name_hash == nhash && !strcmp (p->name, n)) - break; - else - p = p->right; - } - } - if (p == NULL) - return NULL; - } /* while */ - - return (asn1_node) p; -} - - -/******************************************************************/ -/* Function : _asn1_set_value */ -/* Description: sets the field VALUE in a NODE_ASN element. The */ -/* previous value (if exist) will be lost */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to set. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len) -{ - if (node == NULL) - return node; - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } - - if (!len) - return node; - - if (len < sizeof (node->small_value)) - { - node->value = node->small_value; - } - else - { - node->value = malloc (len); - if (node->value == NULL) - return NULL; - } - node->value_len = len; - - memcpy (node->value, value, len); - return node; -} - -/******************************************************************/ -/* Function : _asn1_set_value_lv */ -/* Description: sets the field VALUE in a NODE_ASN element. The */ -/* previous value (if exist) will be lost. The value */ -/* given is stored as an length-value format (LV */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to set. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len) -{ - int len2; - void *temp; - - if (node == NULL) - return node; - - asn1_length_der (len, NULL, &len2); - temp = malloc (len + len2); - if (temp == NULL) - return NULL; - - asn1_octet_der (value, len, temp, &len2); - return _asn1_set_value_m (node, temp, len2); -} - -/* the same as _asn1_set_value except that it sets an already malloc'ed - * value. - */ -asn1_node -_asn1_set_value_m (asn1_node node, void *value, unsigned int len) -{ - if (node == NULL) - return node; - - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } - - if (!len) - return node; - - node->value = value; - node->value_len = len; - - return node; -} - -/******************************************************************/ -/* Function : _asn1_append_value */ -/* Description: appends to the field VALUE in a NODE_ASN element. */ -/* */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to be appended. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_append_value (asn1_node node, const void *value, unsigned int len) -{ - if (node == NULL) - return node; - - if (node->value == NULL) - return _asn1_set_value (node, value, len); - - if (len == 0) - return node; - - if (node->value == node->small_value) - { - /* value is in node */ - int prev_len = node->value_len; - node->value_len += len; - node->value = malloc (node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - - if (prev_len > 0) - memcpy (node->value, node->small_value, prev_len); - - memcpy (&node->value[prev_len], value, len); - - return node; - } - else /* if (node->value != NULL && node->value != node->small_value) */ - { - /* value is allocated */ - int prev_len = node->value_len; - node->value_len += len; - - node->value = _asn1_realloc (node->value, node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - - memcpy (&node->value[prev_len], value, len); - - return node; - } -} - -/******************************************************************/ -/* Function : _asn1_set_name */ -/* Description: sets the field NAME in a NODE_ASN element. The */ -/* previous value (if exist) will be lost */ -/* Parameters: */ -/* node: element pointer. */ -/* name: a null terminated string with the name that you want */ -/* to set. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_set_name (asn1_node node, const char *name) -{ - if (node == NULL) - return node; - - _asn1_str_cpy (node->name, sizeof (node->name), name ? name : ""); - node->name_hash = _asn1_hash_name (node->name); - - return node; -} - -/******************************************************************/ -/* Function : _asn1_cpy_name */ -/* Description: copies the field NAME in a NODE_ASN element. */ -/* Parameters: */ -/* dst: a dest element pointer. */ -/* src: a source element pointer. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -asn1_node -_asn1_cpy_name (asn1_node dst, asn1_node_const src) -{ - if (dst == NULL) - return dst; - - if (src == NULL) - { - dst->name[0] = 0; - dst->name_hash = _asn1_hash_name (dst->name); - return dst; - } - - _asn1_str_cpy (dst->name, sizeof (dst->name), src->name); - dst->name_hash = src->name_hash; - - return dst; -} - -/******************************************************************/ -/* Function : _asn1_set_right */ -/* Description: sets the field RIGHT in a NODE_ASN element. */ -/* Parameters: */ -/* node: element pointer. */ -/* right: pointer to a NODE_ASN element that you want be pointed*/ -/* by NODE. */ -/* Return: pointer to *NODE. */ -/******************************************************************/ -asn1_node -_asn1_set_right (asn1_node node, asn1_node right) -{ - if (node == NULL) - return node; - node->right = right; - if (right) - right->left = node; - return node; -} - - -/******************************************************************/ -/* Function : _asn1_get_last_right */ -/* Description: return the last element along the right chain. */ -/* Parameters: */ -/* node: starting element pointer. */ -/* Return: pointer to the last element along the right chain. */ -/******************************************************************/ -asn1_node -_asn1_get_last_right (asn1_node_const node) -{ - asn1_node_const p; - - if (node == NULL) - return NULL; - p = node; - while (p->right) - p = p->right; - return (asn1_node) p; -} - -/******************************************************************/ -/* Function : _asn1_remove_node */ -/* Description: gets free the memory allocated for an NODE_ASN */ -/* element (not the elements pointed by it). */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* flags: ASN1_DELETE_FLAG_* */ -/******************************************************************/ -void -_asn1_remove_node (asn1_node node, unsigned int flags) -{ - if (node == NULL) - return; - - if (node->value != NULL) - { - if (flags & ASN1_DELETE_FLAG_ZEROIZE) - { - safe_memset(node->value, 0, node->value_len); - } - - if (node->value != node->small_value) - free (node->value); - } - free (node); -} - -/******************************************************************/ -/* Function : _asn1_find_up */ -/* Description: return the father of the NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: Null if not found. */ -/******************************************************************/ -asn1_node -_asn1_find_up (asn1_node_const node) -{ - asn1_node_const p; - - if (node == NULL) - return NULL; - - p = node; - - while ((p->left != NULL) && (p->left->right == p)) - p = p->left; - - return p->left; -} - -static -unsigned _asn1_is_up (asn1_node_const up_cand, asn1_node_const down) -{ - asn1_node_const d, u; - - if (up_cand == NULL || down == NULL) - return 0; - - d = down; - - while ((u = _asn1_find_up(d)) != NULL && u != d) - { - if (u == up_cand) - return 1; - d = u; - } - - return 0; -} - -/******************************************************************/ -/* Function : _asn1_delete_node_from_list */ -/* Description: deletes the list element given */ -/******************************************************************/ -void -_asn1_delete_node_from_list (list_type *list, asn1_node node) -{ - list_type *p = list; - - while (p) - { - if (p->node == node) - p->node = NULL; - p = p->next; - } -} - -/******************************************************************/ -/* Function : _asn1_delete_list */ -/* Description: deletes the list elements (not the elements */ -/* pointed by them). */ -/******************************************************************/ -void -_asn1_delete_list (list_type *e_list) -{ - list_type *p; - - while (e_list) - { - p = e_list; - e_list = e_list->next; - free (p); - } -} - -/******************************************************************/ -/* Function : _asn1_delete_list_and nodes */ -/* Description: deletes the list elements and the elements */ -/* pointed by them. */ -/******************************************************************/ -void -_asn1_delete_list_and_nodes (list_type *e_list) -{ - list_type *p; - - while (e_list) - { - p = e_list; - e_list = e_list->next; - _asn1_remove_node (p->node, 0); - free (p); - } -} - - -char * -_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) -{ - uint64_t d, r; - char temp[LTOSTR_MAX_SIZE]; - int count, k, start; - uint64_t val; - - if (v < 0) - { - str[0] = '-'; - start = 1; - val = -((uint64_t)v); - } - else - { - val = v; - start = 0; - } - - count = 0; - do - { - d = val / 10; - r = val - d * 10; - temp[start + count] = '0' + (char) r; - count++; - val = d; - } - while (val && ((start+count) < LTOSTR_MAX_SIZE-1)); - - for (k = 0; k < count; k++) - str[k + start] = temp[start + count - k - 1]; - str[count + start] = 0; - return str; -} - - -/******************************************************************/ -/* Function : _asn1_change_integer_value */ -/* Description: converts into DER coding the value assign to an */ -/* INTEGER constant. */ -/* Parameters: */ -/* node: root of an ASN1element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_change_integer_value (asn1_node node) -{ - asn1_node p; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; - int len; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_INTEGER) - && (p->type & CONST_ASSIGN)) - { - if (p->value) - { - _asn1_convert_integer (p->value, val, sizeof (val), &len); - asn1_octet_der (val, len, val2, &len); - _asn1_set_value (p, val2, len); - } - } - - if (p->down) - { - p = p->down; - } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - } - - return ASN1_SUCCESS; -} - -#define MAX_CONSTANTS 1024 -/******************************************************************/ -/* Function : _asn1_expand_object_id */ -/* Description: expand the IDs of an OBJECT IDENTIFIER constant. */ -/* Parameters: */ -/* list: root of an object list */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_expand_object_id (list_type **list, asn1_node node) -{ - asn1_node p, p2, p3, p4, p5; - char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; - int move, tlen, tries; - unsigned max_constants; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_str_cpy (name_root, sizeof (name_root), node->name); - - p = node; - move = DOWN; - tries = 0; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) - && (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !c_isdigit (p2->value[0])) - { - _asn1_str_cpy (name2, sizeof (name2), name_root); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - p3 = asn1_find_node (node, name2); - if (!p3 || _asn1_is_up(p2, p3) || - (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - !(p3->type & CONST_ASSIGN)) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_set_down (p, p2->right); - if (p2->down) - _asn1_delete_structure (*list, &p2->down, 0); - _asn1_delete_node_from_list(*list, p2); - _asn1_remove_node (p2, 0); - p2 = p; - p4 = p3->down; - max_constants = 0; - while (p4) - { - if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) - { - max_constants++; - if (max_constants == MAX_CONSTANTS) - return ASN1_RECURSION; - - p5 = - _asn1_add_single_node (ASN1_ETYPE_CONSTANT); - _asn1_set_name (p5, p4->name); - if (p4->value) - { - tlen = _asn1_strlen (p4->value); - if (tlen > 0) - _asn1_set_value (p5, p4->value, tlen + 1); - } - _asn1_add_static_node2(list, p5); - - if (p2 == p) - { - _asn1_set_right (p5, p->down); - _asn1_set_down (p, p5); - } - else - { - _asn1_set_right (p5, p2->right); - _asn1_set_right (p2, p5); - } - p2 = p5; - } - p4 = p4->right; - } - move = DOWN; - - tries++; - if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) - return ASN1_RECURSION; - - continue; - } - } - } - move = DOWN; - } - else - move = RIGHT; - - tries = 0; - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - /*******************************/ - /* expand DEFAULT */ - /*******************************/ - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) - { - _asn1_str_cpy (name2, sizeof (name2), name_root); - _asn1_str_cat (name2, sizeof (name2), "."); - if (p2->value) - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - p3 = asn1_find_node (node, name2); - if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) - || !(p3->type & CONST_ASSIGN)) - return ASN1_ELEMENT_NOT_FOUND; - p4 = p3->down; - name2[0] = 0; - while (p4) - { - if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) - { - if (p4->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - if (name2[0]) - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), - (char *) p4->value); - } - p4 = p4->right; - } - tlen = strlen (name2); - if (tlen > 0) - _asn1_set_value (p2, name2, tlen + 1); - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_type_set_config */ -/* Description: sets the CONST_SET and CONST_NOT_USED properties */ -/* in the fields of the SET elements. */ -/* Parameters: */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_type_set_config (asn1_node node) -{ - asn1_node p, p2; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_SET) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - p2->type |= CONST_SET | CONST_NOT_USED; - p2 = p2->right; - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p && p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_check_identifier */ -/* Description: checks the definitions of all the identifiers */ -/* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */ -/* The _asn1_identifierMissing global variable is filled if */ -/* necessary. */ -/* Parameters: */ -/* node: root of an ASN1 element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ -/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_check_identifier (asn1_node_const node) -{ - asn1_node_const p, p2; - char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p->value); - p2 = asn1_find_node (node, name2); - if (p2 == NULL) - { - if (p->value) - _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p->value); - else - _asn1_strcpy (_asn1_identifierMissing, "(null)"); - return ASN1_IDENTIFIER_NOT_FOUND; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT)) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - if (p2->value) - { - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); - } - else - _asn1_strcpy (_asn1_identifierMissing, "(null)"); - - p2 = asn1_find_node (node, name2); - if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) || - !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !c_isdigit (p2->value[0])) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); - _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); - - p2 = asn1_find_node (node, name2); - if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) - || !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; - } - } - } - - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (p) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - - return ASN1_SUCCESS; -} - - -/******************************************************************/ -/* Function : _asn1_set_default_tag */ -/* Description: sets the default IMPLICIT or EXPLICIT property in */ -/* the tagged elements that don't have this declaration. */ -/* Parameters: */ -/* node: pointer to a DEFINITIONS element. */ -/* Return: */ -/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */ -/* a DEFINITIONS element, */ -/* otherwise ASN1_SUCCESS */ -/******************************************************************/ -int -_asn1_set_default_tag (asn1_node node) -{ - asn1_node p; - - if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS)) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_TAG) && - !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) - { - if (node->type & CONST_EXPLICIT) - p->type |= CONST_EXPLICIT; - else - p->type |= CONST_IMPLICIT; - } - - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p && p->right) - { - p = p->right; - break; - } - } - } - } - - return ASN1_SUCCESS; -} diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h deleted file mode 100644 index 598e684..0000000 --- a/lib/minitasn1/parser_aux.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2000-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifndef _PARSER_AUX_H -#define _PARSER_AUX_H - -/***********************************************/ -/* Type: list_type */ -/* Description: type used in the list during */ -/* the structure creation. */ -/***********************************************/ -typedef struct list_struct -{ - asn1_node node; - struct list_struct *next; -} list_type; - -/***************************************/ -/* Functions used by ASN.1 parser */ -/***************************************/ -asn1_node _asn1_add_static_node (list_type **e_list, unsigned int type); - -void _asn1_delete_list (list_type *e_list); - -void _asn1_delete_list_and_nodes (list_type *e_list); - -void _asn1_delete_node_from_list (list_type *list, asn1_node node); - -asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len); - -asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len); - -asn1_node -_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len); - -asn1_node -_asn1_append_value (asn1_node node, const void *value, unsigned int len); - -asn1_node _asn1_set_name (asn1_node node, const char *name); - -asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src); - -asn1_node _asn1_set_right (asn1_node node, asn1_node right); - -asn1_node _asn1_get_last_right (asn1_node_const node); - -void _asn1_remove_node (asn1_node node, unsigned int flags); - -/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ -#define LTOSTR_MAX_SIZE 22 -char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); - -asn1_node _asn1_find_up (asn1_node_const node); - -int _asn1_change_integer_value (asn1_node node); - -#define EXPAND_OBJECT_ID_MAX_RECURSION 16 -int _asn1_expand_object_id (list_type **list, asn1_node node); - -int _asn1_type_set_config (asn1_node node); - -int _asn1_check_identifier (asn1_node_const node); - -int _asn1_set_default_tag (asn1_node node); - -/******************************************************************/ -/* Function : _asn1_get_right */ -/* Description: returns the element pointed by the RIGHT field of */ -/* a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: field RIGHT of NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_get_right (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return node->right; -} - -/******************************************************************/ -/* Function : _asn1_set_down */ -/* Description: sets the field DOWN in a NODE_ASN element. */ -/* Parameters: */ -/* node: element pointer. */ -/* down: pointer to a NODE_ASN element that you want be pointed */ -/* by NODE. */ -/* Return: pointer to *NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_set_down (asn1_node node, asn1_node down) -{ - if (node == NULL) - return node; - node->down = down; - if (down) - down->left = node; - return node; -} - -/******************************************************************/ -/* Function : _asn1_get_down */ -/* Description: returns the element pointed by the DOWN field of */ -/* a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: field DOWN of NODE. */ -/******************************************************************/ -inline static asn1_node -_asn1_get_down (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return node->down; -} - -/******************************************************************/ -/* Function : _asn1_get_name */ -/* Description: returns the name of a NODE_ASN element. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: a null terminated string. */ -/******************************************************************/ -inline static char * -_asn1_get_name (asn1_node_const node) -{ - if (node == NULL) - return NULL; - return (char *) node->name; -} - -/******************************************************************/ -/* Function : _asn1_mod_type */ -/* Description: change the field TYPE of an NODE_ASN element. */ -/* The new value is the old one | (bitwise or) the */ -/* paramener VALUE. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* value: the integer value that must be or-ed with the current */ -/* value of field TYPE. */ -/* Return: NODE pointer. */ -/******************************************************************/ -inline static asn1_node -_asn1_mod_type (asn1_node node, unsigned int value) -{ - if (node == NULL) - return node; - node->type |= value; - return node; -} - -#endif diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c deleted file mode 100644 index 8189c56..0000000 --- a/lib/minitasn1/structure.c +++ /dev/null @@ -1,1220 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - - -/*****************************************************/ -/* File: structure.c */ -/* Description: Functions to create and delete an */ -/* ASN1 tree. */ -/*****************************************************/ - - -#include -#include -#include "parser_aux.h" -#include - - -extern char _asn1_identifierMissing[]; - - -/******************************************************/ -/* Function : _asn1_add_single_node */ -/* Description: creates a new NODE_ASN element. */ -/* Parameters: */ -/* type: type of the new element (see ASN1_ETYPE_ */ -/* and CONST_ constants). */ -/* Return: pointer to the new element. */ -/******************************************************/ -asn1_node -_asn1_add_single_node (unsigned int type) -{ - asn1_node punt; - - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; - - punt->type = type; - - return punt; -} - - -/******************************************************************/ -/* Function : _asn1_find_left */ -/* Description: returns the NODE_ASN element with RIGHT field that*/ -/* points the element NODE. */ -/* Parameters: */ -/* node: NODE_ASN element pointer. */ -/* Return: NULL if not found. */ -/******************************************************************/ -asn1_node -_asn1_find_left (asn1_node_const node) -{ - if ((node == NULL) || (node->left == NULL) || (node->left->down == node)) - return NULL; - - return node->left; -} - - -int -_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, - char *vector_name) -{ - FILE *file; - asn1_node_const p; - unsigned long t; - - file = fopen (output_file_name, "w"); - - if (file == NULL) - return ASN1_FILE_NOT_FOUND; - - fprintf (file, "#if HAVE_CONFIG_H\n"); - fprintf (file, "# include \"config.h\"\n"); - fprintf (file, "#endif\n\n"); - - fprintf (file, "#include \n\n"); - - fprintf (file, "const asn1_static_node %s[] = {\n", vector_name); - - p = pointer; - - while (p) - { - fprintf (file, " { "); - - if (p->name[0] != 0) - fprintf (file, "\"%s\", ", p->name); - else - fprintf (file, "NULL, "); - - t = p->type; - if (p->down) - t |= CONST_DOWN; - if (p->right) - t |= CONST_RIGHT; - - fprintf (file, "%lu, ", t); - - if (p->value) - fprintf (file, "\"%s\"},\n", p->value); - else - fprintf (file, "NULL },\n"); - - if (p->down) - { - p = p->down; - } - else if (p->right) - { - p = p->right; - } - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == pointer) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } - } - } - } - - fprintf (file, " { NULL, 0, NULL }\n};\n"); - - fclose (file); - - return ASN1_SUCCESS; -} - - -/** - * asn1_array2tree: - * @array: specify the array that contains ASN.1 declarations - * @definitions: return the pointer to the structure created by - * *ARRAY ASN.1 declarations - * @errorDescription: return the error description. - * - * Creates the structures needed to manage the ASN.1 definitions. - * @array is a vector created by asn1_parser2array(). - * - * Returns: %ASN1_SUCCESS if structure was created correctly, - * %ASN1_ELEMENT_NOT_EMPTY if *@definitions not NULL, - * %ASN1_IDENTIFIER_NOT_FOUND if in the file there is an identifier - * that is not defined (see @errorDescription for more information), - * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong. - **/ -int -asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, - char *errorDescription) -{ - asn1_node p, p_last = NULL; - unsigned long k; - int move; - int result; - unsigned int type; - list_type *e_list = NULL; - - if (errorDescription) - errorDescription[0] = 0; - - if (*definitions != NULL) - return ASN1_ELEMENT_NOT_EMPTY; - - move = UP; - - for (k = 0; array[k].value || array[k].type || array[k].name; k++) - { - type = convert_old_type (array[k].type); - - p = _asn1_add_static_node (&e_list, type & (~CONST_DOWN)); - if (array[k].name) - _asn1_set_name (p, array[k].name); - if (array[k].value) - _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); - - if (*definitions == NULL) - *definitions = p; - - if (move == DOWN) - { - if (p_last && p_last->down) - _asn1_delete_structure (e_list, &p_last->down, 0); - _asn1_set_down (p_last, p); - } - else if (move == RIGHT) - { - if (p_last && p_last->right) - _asn1_delete_structure (e_list, &p_last->right, 0); - _asn1_set_right (p_last, p); - } - - p_last = p; - - if (type & CONST_DOWN) - move = DOWN; - else if (type & CONST_RIGHT) - move = RIGHT; - else - { - while (p_last != *definitions) - { - p_last = _asn1_find_up (p_last); - - if (p_last == NULL) - break; - - if (p_last->type & CONST_RIGHT) - { - p_last->type &= ~CONST_RIGHT; - move = RIGHT; - break; - } - } /* while */ - } - } /* while */ - - if (p_last == *definitions) - { - result = _asn1_check_identifier (*definitions); - if (result == ASN1_SUCCESS) - { - _asn1_change_integer_value (*definitions); - result = _asn1_expand_object_id (&e_list, *definitions); - } - } - else - { - result = ASN1_ARRAY_ERROR; - } - - if (errorDescription != NULL) - { - if (result == ASN1_IDENTIFIER_NOT_FOUND) - { - Estrcpy (errorDescription, ":: identifier '"); - Estrcat (errorDescription, _asn1_identifierMissing); - Estrcat (errorDescription, "' not found"); - } - else - errorDescription[0] = 0; - } - - if (result != ASN1_SUCCESS) - { - _asn1_delete_list_and_nodes (e_list); - *definitions = NULL; - } - else - _asn1_delete_list (e_list); - - return result; -} - -/** - * asn1_delete_structure: - * @structure: pointer to the structure that you want to delete. - * - * Deletes the structure *@structure. At the end, *@structure is set - * to NULL. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * *@structure was NULL. - **/ -int -asn1_delete_structure (asn1_node * structure) -{ - return _asn1_delete_structure (NULL, structure, 0); -} - -/** - * asn1_delete_structure2: - * @structure: pointer to the structure that you want to delete. - * @flags: additional flags (see %ASN1_DELETE_FLAG) - * - * Deletes the structure *@structure. At the end, *@structure is set - * to NULL. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * *@structure was NULL. - **/ -int -asn1_delete_structure2 (asn1_node * structure, unsigned int flags) -{ - return _asn1_delete_structure (NULL, structure, flags); -} - -int -_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags) -{ - asn1_node p, p2, p3; - - if (*structure == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *structure; - while (p) - { - if (p->down) - { - p = p->down; - } - else - { /* no down */ - p2 = p->right; - if (p != *structure) - { - p3 = _asn1_find_up (p); - _asn1_set_down (p3, p2); - if (e_list) - _asn1_delete_node_from_list (e_list, p); - _asn1_remove_node (p, flags); - p = p3; - } - else - { /* p==root */ - p3 = _asn1_find_left (p); - if (!p3) - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - if (p->right) - p->right->left = NULL; - } - } - else - _asn1_set_right (p3, p2); - if (e_list) - _asn1_delete_node_from_list (e_list, p); - _asn1_remove_node (p, flags); - p = NULL; - } - } - } - - *structure = NULL; - return ASN1_SUCCESS; -} - - -/** - * asn1_delete_element: - * @structure: pointer to the structure that contains the element you - * want to delete. - * @element_name: element's name you want to delete. - * - * Deletes the element named *@element_name inside *@structure. - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * the @element_name was not found. - **/ -int -asn1_delete_element (asn1_node structure, const char *element_name) -{ - asn1_node p2, p3, source_node; - - source_node = asn1_find_node (structure, element_name); - - if (source_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p2 = source_node->right; - p3 = _asn1_find_left (source_node); - if (!p3) - { - p3 = _asn1_find_up (source_node); - if (p3) - _asn1_set_down (p3, p2); - else if (source_node->right) - source_node->right->left = NULL; - } - else - _asn1_set_right (p3, p2); - - return asn1_delete_structure (&source_node); -} - -#ifndef __clang_analyzer__ -asn1_node -_asn1_copy_structure3 (asn1_node_const source_node) -{ - asn1_node_const p_s; - asn1_node dest_node, p_d, p_d_prev; - int move; - - if (source_node == NULL) - return NULL; - - dest_node = _asn1_add_single_node (source_node->type); - - p_s = source_node; - p_d = dest_node; - - move = DOWN; - - do - { - if (move != UP) - { - if (p_s->name[0] != 0) - _asn1_cpy_name (p_d, p_s); - if (p_s->value) - _asn1_set_value (p_d, p_s->value, p_s->value_len); - if (p_s->down) - { - p_s = p_s->down; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_down (p_d_prev, p_d); - continue; - } - p_d->start = p_s->start; - p_d->end = p_s->end; - } - - if (p_s == source_node) - break; - - if (p_s->right) - { - move = RIGHT; - p_s = p_s->right; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_right (p_d_prev, p_d); - } - else - { - move = UP; - p_s = _asn1_find_up (p_s); - p_d = _asn1_find_up (p_d); - } - } - while (p_s != source_node); - return dest_node; -} -#else - -/* Non-production code */ -asn1_node -_asn1_copy_structure3 (asn1_node_const source_node) -{ - return NULL; -} -#endif /* __clang_analyzer__ */ - - -static asn1_node -_asn1_copy_structure2 (asn1_node_const root, const char *source_name) -{ - asn1_node source_node; - - source_node = asn1_find_node (root, source_name); - - return _asn1_copy_structure3 (source_node); - -} - - -static int -_asn1_type_choice_config (asn1_node node) -{ - asn1_node p, p2, p3, p4; - int move, tlen; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_CHOICE) - && (p->type & CONST_TAG)) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p2->type |= CONST_TAG; - p3 = _asn1_find_left (p2); - while (p3) - { - if (type_field (p3->type) == ASN1_ETYPE_TAG) - { - p4 = _asn1_add_single_node (p3->type); - tlen = _asn1_strlen (p3->value); - if (tlen > 0) - _asn1_set_value (p4, p3->value, tlen + 1); - _asn1_set_right (p4, p2->down); - _asn1_set_down (p2, p4); - } - p3 = _asn1_find_left (p3); - } - } - p2 = p2->right; - } - p->type &= ~(CONST_TAG); - p2 = p->down; - while (p2) - { - p3 = p2->right; - if (type_field (p2->type) == ASN1_ETYPE_TAG) - asn1_delete_structure (&p2); - p2 = p3; - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -static int -_asn1_expand_identifier (asn1_node * node, asn1_node_const root) -{ - asn1_node p, p2, p3; - char name2[ASN1_MAX_NAME_SIZE + 2]; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *node; - move = DOWN; - - while (!((p == *node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value); - p2 = _asn1_copy_structure2 (root, name2); - if (p2 == NULL) - { - return ASN1_IDENTIFIER_NOT_FOUND; - } - _asn1_cpy_name (p2, p); - p2->right = p->right; - p2->left = p->left; - if (p->right) - p->right->left = p2; - p3 = p->down; - if (p3) - { - while (p3->right) - p3 = p3->right; - _asn1_set_right (p3, p2->down); - _asn1_set_down (p2, p->down); - } - - p3 = _asn1_find_left (p); - if (p3) - _asn1_set_right (p3, p2); - else - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - p2->left = NULL; - } - } - - if (p->type & CONST_SIZE) - p2->type |= CONST_SIZE; - if (p->type & CONST_TAG) - p2->type |= CONST_TAG; - if (p->type & CONST_OPTION) - p2->type |= CONST_OPTION; - if (p->type & CONST_DEFAULT) - p2->type |= CONST_DEFAULT; - if (p->type & CONST_SET) - p2->type |= CONST_SET; - if (p->type & CONST_NOT_USED) - p2->type |= CONST_NOT_USED; - - if (p == *node) - *node = p2; - _asn1_remove_node (p, 0); - p = p2; - move = DOWN; - continue; - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - - if (p == *node) - { - move = UP; - continue; - } - - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_SUCCESS; -} - - -/** - * asn1_create_element: - * @definitions: pointer to the structure returned by "parser_asn1" function - * @source_name: the name of the type of the new structure (must be - * inside p_structure). - * @element: pointer to the structure created. - * - * Creates a structure of type @source_name. Example using - * "pkix.asn": - * - * rc = asn1_create_element(cert_def, "PKIX1.Certificate", certptr); - * - * Returns: %ASN1_SUCCESS if creation OK, %ASN1_ELEMENT_NOT_FOUND if - * @source_name is not known. - **/ -int -asn1_create_element (asn1_node_const definitions, const char *source_name, - asn1_node * element) -{ - asn1_node dest_node; - int res; - - dest_node = _asn1_copy_structure2 (definitions, source_name); - - if (dest_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_set_name (dest_node, ""); - - res = _asn1_expand_identifier (&dest_node, definitions); - _asn1_type_choice_config (dest_node); - - *element = dest_node; - - return res; -} - - -/** - * asn1_print_structure: - * @out: pointer to the output file (e.g. stdout). - * @structure: pointer to the structure that you want to visit. - * @name: an element of the structure - * @mode: specify how much of the structure to print, can be - * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE, - * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL. - * - * Prints on the @out file descriptor the structure's tree starting - * from the @name element inside the structure @structure. - **/ -void -asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, - int mode) -{ - asn1_node_const p, root; - int k, indent = 0, len, len2, len3; - - if (out == NULL) - return; - - root = asn1_find_node (structure, name); - - if (root == NULL) - return; - - p = root; - while (p) - { - if (mode == ASN1_PRINT_ALL) - { - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - } - - if (mode != ASN1_PRINT_NAME) - { - unsigned type = type_field (p->type); - switch (type) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:CONST"); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:TAG"); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:SIZE"); - break; - case ASN1_ETYPE_DEFAULT: - fprintf (out, "type:DEFAULT"); - break; - case ASN1_ETYPE_IDENTIFIER: - fprintf (out, "type:IDENTIFIER"); - break; - case ASN1_ETYPE_ANY: - fprintf (out, "type:ANY"); - break; - case ASN1_ETYPE_CHOICE: - fprintf (out, "type:CHOICE"); - break; - case ASN1_ETYPE_DEFINITIONS: - fprintf (out, "type:DEFINITIONS"); - break; - CASE_HANDLED_ETYPES: - fprintf (out, "%s", _asn1_tags[type].desc); - break; - default: - break; - } - } - - if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL)) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_DEFAULT: - if (p->value) - fprintf (out, " value:%s", p->value); - else if (p->type & CONST_TRUE) - fprintf (out, " value:TRUE"); - else if (p->type & CONST_FALSE) - fprintf (out, " value:FALSE"); - break; - case ASN1_ETYPE_IDENTIFIER: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_INTEGER: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_ENUMERATED: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BOOLEAN: - if (p->value) - { - if (p->value[0] == 'T') - fprintf (out, " value:TRUE"); - else if (p->value[0] == 'F') - fprintf (out, " value:FALSE"); - } - break; - case ASN1_ETYPE_BIT_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - if (len > 0) - { - fprintf (out, " value(%i):", - (len - 1) * 8 - (p->value[len2])); - for (k = 1; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (p->value) - { - fprintf (out, " value:"); - for (k = 0; k < p->value_len; k++) - fprintf (out, "%c", (p->value)[k]); - } - break; - case ASN1_ETYPE_GENERALSTRING: - case ASN1_ETYPE_NUMERIC_STRING: - case ASN1_ETYPE_IA5_STRING: - case ASN1_ETYPE_TELETEX_STRING: - case ASN1_ETYPE_PRINTABLE_STRING: - case ASN1_ETYPE_UNIVERSAL_STRING: - case ASN1_ETYPE_UTF8_STRING: - case ASN1_ETYPE_VISIBLE_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%c", (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_OCTET_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_OBJECT_ID: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_ANY: - if (p->value) - { - len3 = -1; - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - fprintf (out, " value:"); - if (len2 > 0) - for (k = 0; k < len2; k++) - fprintf (out, "%02x", (unsigned) (p->value)[k + len3]); - } - break; - case ASN1_ETYPE_SET: - case ASN1_ETYPE_SET_OF: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_DEFINITIONS: - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_NULL: - break; - default: - break; - } - } - - if (mode == ASN1_PRINT_ALL) - { - if (p->type & 0x1FFFFF00) - { - fprintf (out, " attr:"); - if (p->type & CONST_UNIVERSAL) - fprintf (out, "UNIVERSAL,"); - if (p->type & CONST_PRIVATE) - fprintf (out, "PRIVATE,"); - if (p->type & CONST_APPLICATION) - fprintf (out, "APPLICATION,"); - if (p->type & CONST_EXPLICIT) - fprintf (out, "EXPLICIT,"); - if (p->type & CONST_IMPLICIT) - fprintf (out, "IMPLICIT,"); - if (p->type & CONST_TAG) - fprintf (out, "TAG,"); - if (p->type & CONST_DEFAULT) - fprintf (out, "DEFAULT,"); - if (p->type & CONST_TRUE) - fprintf (out, "TRUE,"); - if (p->type & CONST_FALSE) - fprintf (out, "FALSE,"); - if (p->type & CONST_LIST) - fprintf (out, "LIST,"); - if (p->type & CONST_MIN_MAX) - fprintf (out, "MIN_MAX,"); - if (p->type & CONST_OPTION) - fprintf (out, "OPTION,"); - if (p->type & CONST_1_PARAM) - fprintf (out, "1_PARAM,"); - if (p->type & CONST_SIZE) - fprintf (out, "SIZE,"); - if (p->type & CONST_DEFINED_BY) - fprintf (out, "DEF_BY,"); - if (p->type & CONST_GENERALIZED) - fprintf (out, "GENERALIZED,"); - if (p->type & CONST_UTC) - fprintf (out, "UTC,"); - if (p->type & CONST_SET) - fprintf (out, "SET,"); - if (p->type & CONST_NOT_USED) - fprintf (out, "NOT_USED,"); - if (p->type & CONST_ASSIGN) - fprintf (out, "ASSIGNMENT,"); - } - } - - if (mode == ASN1_PRINT_ALL) - { - fprintf (out, "\n"); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - fprintf (out, "\n"); - } - } - - if (p->down) - { - p = p->down; - indent += 2; - } - else if (p == root) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == root) - { - p = NULL; - break; - } - indent -= 2; - if (p->right) - { - p = p->right; - break; - } - } - } - } -} - - - -/** - * asn1_number_of_elements: - * @element: pointer to the root of an ASN1 structure. - * @name: the name of a sub-structure of ROOT. - * @num: pointer to an integer where the result will be stored - * - * Counts the number of elements of a sub-structure called NAME with - * names equal to "?1","?2", ... - * - * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if - * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL. - **/ -int -asn1_number_of_elements (asn1_node_const element, const char *name, int *num) -{ - asn1_node_const node, p; - - if (num == NULL) - return ASN1_GENERIC_ERROR; - - *num = 0; - - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node->down; - - while (p) - { - if (p->name[0] == '?') - (*num)++; - p = p->right; - } - - return ASN1_SUCCESS; -} - - -/** - * asn1_find_structure_from_oid: - * @definitions: ASN1 definitions - * @oidValue: value of the OID to search (e.g. "1.2.3.4"). - * - * Search the structure that is defined just after an OID definition. - * - * Returns: %NULL when @oidValue not found, otherwise the pointer to a - * constant string that contains the element name defined just after - * the OID. - **/ -const char * -asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue) -{ - char name[2 * ASN1_MAX_NAME_SIZE + 2]; - char value[ASN1_MAX_NAME_SIZE]; - asn1_node p; - int len; - int result; - const char *definitionsName; - - if ((definitions == NULL) || (oidValue == NULL)) - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - - definitionsName = definitions->name; - - /* search the OBJECT_ID into definitions */ - p = definitions->down; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name); - - len = ASN1_MAX_NAME_SIZE; - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value))) - { - p = p->right; - if (p == NULL) /* reach the end of ASN1 definitions */ - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - - return p->name; - } - } - p = p->right; - } - - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ -} - -/** - * asn1_copy_node: - * @dst: Destination asn1 node. - * @dst_name: Field name in destination node. - * @src: Source asn1 node. - * @src_name: Field name in source node. - * - * Create a deep copy of a asn1_node variable. That - * function requires @dst to be expanded using asn1_create_element(). - * - * Returns: Return %ASN1_SUCCESS on success. - **/ -int -asn1_copy_node (asn1_node dst, const char *dst_name, - asn1_node_const src, const char *src_name) -{ - int result; - asn1_node dst_node; - void *data = NULL; - int size = 0; - - result = asn1_der_coding (src, src_name, NULL, &size, NULL); - if (result != ASN1_MEM_ERROR) - return result; - - data = malloc (size); - if (data == NULL) - return ASN1_MEM_ERROR; - - result = asn1_der_coding (src, src_name, data, &size, NULL); - if (result != ASN1_SUCCESS) - { - free (data); - return result; - } - - dst_node = asn1_find_node (dst, dst_name); - if (dst_node == NULL) - { - free (data); - return ASN1_ELEMENT_NOT_FOUND; - } - - result = asn1_der_decoding (&dst_node, data, size, NULL); - - free (data); - - return result; -} - -/** - * asn1_dup_node: - * @src: Source asn1 node. - * @src_name: Field name in source node. - * - * Create a deep copy of a asn1_node variable. This function - * will return an exact copy of the provided structure. - * - * Returns: Return %NULL on failure. - **/ -asn1_node -asn1_dup_node (asn1_node_const src, const char *src_name) -{ - return _asn1_copy_structure2(src, src_name); -} diff --git a/lib/minitasn1/structure.h b/lib/minitasn1/structure.h deleted file mode 100644 index 99e685d..0000000 --- a/lib/minitasn1/structure.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2002-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -/*************************************************/ -/* File: structure.h */ -/* Description: list of exported object by */ -/* "structure.c" */ -/*************************************************/ - -#ifndef _STRUCTURE_H -#define _STRUCTURE_H - -#include "parser_aux.h" // list_type - -int _asn1_create_static_structure (asn1_node_const pointer, - char *output_file_name, char *vector_name); - -asn1_node _asn1_copy_structure3 (asn1_node_const source_node); - -asn1_node _asn1_add_single_node (unsigned int type); - -asn1_node _asn1_find_left (asn1_node_const node); - -int -_asn1_delete_structure (list_type *e_list, asn1_node *structure, unsigned int flags); - -#endif diff --git a/lib/minitasn1/version.c b/lib/minitasn1/version.c deleted file mode 100644 index 25f8a8f..0000000 --- a/lib/minitasn1/version.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2000-2014 Free Software Foundation, Inc. - * - * This file is part of LIBTASN1. - * - * The LIBTASN1 library is free software; you can redistribute it - * and/or modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include /* for strverscmp */ - -#include "libtasn1.h" - -/** - * asn1_check_version: - * @req_version: Required version number, or %NULL. - * - * Check that the version of the library is at minimum the - * requested one and return the version string; return %NULL if the - * condition is not satisfied. If a %NULL is passed to this function, - * no check is done, but the version string is simply returned. - * - * See %ASN1_VERSION for a suitable @req_version string. - * - * Returns: Version string of run-time library, or %NULL if the - * run-time library does not meet the required version number. - */ -const char * -asn1_check_version (const char *req_version) -{ - if (!req_version || strverscmp (req_version, ASN1_VERSION) <= 0) - return ASN1_VERSION; - - return NULL; -} diff --git a/src/libopts/ag-char-map.h b/src/libopts/ag-char-map.h deleted file mode 100644 index cced230..0000000 --- a/src/libopts/ag-char-map.h +++ /dev/null @@ -1,526 +0,0 @@ -/* - * 29 bits for 46 character classifications - * generated by char-mapper on 08/26/18 at 10:44:22 - * - * This file contains the character classifications - * used by AutoGen and AutoOpts for identifying tokens. - * The table is static scope, so %guard is empty. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ -#ifndef AG_CHAR_MAP_H_GUARD -#define AG_CHAR_MAP_H_GUARD 1 - -#ifdef HAVE_CONFIG_H -# if defined(HAVE_INTTYPES_H) -# include - -# elif defined(HAVE_STDINT_H) -# include - -# elif !defined(HAVE_UINT32_T) -# if SIZEOF_INT == 4 - typedef unsigned int uint32_t; -# elif SIZEOF_LONG == 4 - typedef unsigned long uint32_t; -# endif -# endif /* HAVE_*INT*_H header */ - -#else /* not HAVE_CONFIG_H -- */ -# include -#endif /* HAVE_CONFIG_H */ - -#if 0 /* mapping specification source (from autogen.map) */ -// -// %guard -// %file ag-char-map.h -// %backup -// %optimize -// -// %comment -- see above -// % -// -// newline "\n" -// nul-byte "\x00" -// dir-sep "/\\" -// percent "%" -// comma "," -// colon ":" -// underscore "_" -// plus "+" -// dollar "$" -// option-marker "-" -// -// horiz-white "\t " -// alt-white "\v\f\r\b" -// whitespace +horiz-white +newline +alt-white -// non-nl-white +horiz-white +alt-white -// quote "'\"" -// parentheses "()" -// -// graphic "!-~" -// inversion "~-" -// oct-digit "0-7" -// dec-digit "89" +oct-digit -// hex-digit "a-fA-F" +dec-digit -// lower-case "a-z" -// upper-case "A-Z" -// alphabetic +lower-case +upper-case -// alphanumeric +alphabetic +dec-digit -// var-first +underscore +alphabetic -// variable-name +var-first +dec-digit -// option-name "^-" +variable-name -// value-name +colon +option-name -// name-sep "[.]" -// compound-name +value-name +name-sep +horiz-white -// scheme-note +parentheses +quote -// -// unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses -// end-xml-token "/>" +whitespace -// plus-n-space +plus +whitespace -// punctuation "!-~" -alphanumeric -"_" -// suffix "-._" +alphanumeric -// suffix-fmt +percent +suffix +dir-sep -// false-type "nNfF0" +nul-byte -// file-name +dir-sep +suffix -// end-token +nul-byte +whitespace -// end-list-entry +comma +end-token -// set-separator "|+-!" +end-list-entry -// signed-number +inversion +dec-digit -// make-script +dollar +newline -// load-line-skip +horiz-white +option-marker -// -#endif /* 0 -- mapping spec. source */ - - -typedef uint32_t ag_char_map_mask_t; - -#define IS_NEWLINE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000001) -#define SPN_NEWLINE_CHARS(_s) spn_ag_char_map_chars(_s, 0) -#define BRK_NEWLINE_CHARS(_s) brk_ag_char_map_chars(_s, 0) -#define SPN_NEWLINE_BACK(s,e) spn_ag_char_map_back(s, e, 0) -#define BRK_NEWLINE_BACK(s,e) brk_ag_char_map_back(s, e, 0) -#define IS_NUL_BYTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000002) -#define SPN_NUL_BYTE_CHARS(_s) spn_ag_char_map_chars(_s, 1) -#define BRK_NUL_BYTE_CHARS(_s) brk_ag_char_map_chars(_s, 1) -#define SPN_NUL_BYTE_BACK(s,e) spn_ag_char_map_back(s, e, 1) -#define BRK_NUL_BYTE_BACK(s,e) brk_ag_char_map_back(s, e, 1) -#define IS_DIR_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000004) -#define SPN_DIR_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 2) -#define BRK_DIR_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 2) -#define SPN_DIR_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 2) -#define BRK_DIR_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 2) -#define IS_PERCENT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000008) -#define SPN_PERCENT_CHARS(_s) spn_ag_char_map_chars(_s, 3) -#define BRK_PERCENT_CHARS(_s) brk_ag_char_map_chars(_s, 3) -#define SPN_PERCENT_BACK(s,e) spn_ag_char_map_back(s, e, 3) -#define BRK_PERCENT_BACK(s,e) brk_ag_char_map_back(s, e, 3) -#define IS_COMMA_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000010) -#define SPN_COMMA_CHARS(_s) spn_ag_char_map_chars(_s, 4) -#define BRK_COMMA_CHARS(_s) brk_ag_char_map_chars(_s, 4) -#define SPN_COMMA_BACK(s,e) spn_ag_char_map_back(s, e, 4) -#define BRK_COMMA_BACK(s,e) brk_ag_char_map_back(s, e, 4) -#define IS_COLON_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000020) -#define SPN_COLON_CHARS(_s) spn_ag_char_map_chars(_s, 5) -#define BRK_COLON_CHARS(_s) brk_ag_char_map_chars(_s, 5) -#define SPN_COLON_BACK(s,e) spn_ag_char_map_back(s, e, 5) -#define BRK_COLON_BACK(s,e) brk_ag_char_map_back(s, e, 5) -#define IS_UNDERSCORE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000040) -#define SPN_UNDERSCORE_CHARS(_s) spn_ag_char_map_chars(_s, 6) -#define BRK_UNDERSCORE_CHARS(_s) brk_ag_char_map_chars(_s, 6) -#define SPN_UNDERSCORE_BACK(s,e) spn_ag_char_map_back(s, e, 6) -#define BRK_UNDERSCORE_BACK(s,e) brk_ag_char_map_back(s, e, 6) -#define IS_PLUS_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000080) -#define SPN_PLUS_CHARS(_s) spn_ag_char_map_chars(_s, 7) -#define BRK_PLUS_CHARS(_s) brk_ag_char_map_chars(_s, 7) -#define SPN_PLUS_BACK(s,e) spn_ag_char_map_back(s, e, 7) -#define BRK_PLUS_BACK(s,e) brk_ag_char_map_back(s, e, 7) -#define IS_DOLLAR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000100) -#define SPN_DOLLAR_CHARS(_s) spn_ag_char_map_chars(_s, 8) -#define BRK_DOLLAR_CHARS(_s) brk_ag_char_map_chars(_s, 8) -#define SPN_DOLLAR_BACK(s,e) spn_ag_char_map_back(s, e, 8) -#define BRK_DOLLAR_BACK(s,e) brk_ag_char_map_back(s, e, 8) -#define IS_OPTION_MARKER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000200) -#define SPN_OPTION_MARKER_CHARS(_s) spn_ag_char_map_chars(_s, 9) -#define BRK_OPTION_MARKER_CHARS(_s) brk_ag_char_map_chars(_s, 9) -#define SPN_OPTION_MARKER_BACK(s,e) spn_ag_char_map_back(s, e, 9) -#define BRK_OPTION_MARKER_BACK(s,e) brk_ag_char_map_back(s, e, 9) -#define IS_HORIZ_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000400) -#define SPN_HORIZ_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 10) -#define BRK_HORIZ_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 10) -#define SPN_HORIZ_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 10) -#define BRK_HORIZ_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 10) -#define IS_ALT_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000800) -#define SPN_ALT_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 11) -#define BRK_ALT_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 11) -#define SPN_ALT_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 11) -#define BRK_ALT_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 11) -#define IS_WHITESPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C01) -#define SPN_WHITESPACE_CHARS(_s) spn_ag_char_map_chars(_s, 12) -#define BRK_WHITESPACE_CHARS(_s) brk_ag_char_map_chars(_s, 12) -#define SPN_WHITESPACE_BACK(s,e) spn_ag_char_map_back(s, e, 12) -#define BRK_WHITESPACE_BACK(s,e) brk_ag_char_map_back(s, e, 12) -#define IS_NON_NL_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C00) -#define SPN_NON_NL_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 13) -#define BRK_NON_NL_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 13) -#define SPN_NON_NL_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 13) -#define BRK_NON_NL_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 13) -#define IS_QUOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00001000) -#define SPN_QUOTE_CHARS(_s) spn_ag_char_map_chars(_s, 14) -#define BRK_QUOTE_CHARS(_s) brk_ag_char_map_chars(_s, 14) -#define SPN_QUOTE_BACK(s,e) spn_ag_char_map_back(s, e, 14) -#define BRK_QUOTE_BACK(s,e) brk_ag_char_map_back(s, e, 14) -#define IS_PARENTHESES_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00002000) -#define SPN_PARENTHESES_CHARS(_s) spn_ag_char_map_chars(_s, 15) -#define BRK_PARENTHESES_CHARS(_s) brk_ag_char_map_chars(_s, 15) -#define SPN_PARENTHESES_BACK(s,e) spn_ag_char_map_back(s, e, 15) -#define BRK_PARENTHESES_BACK(s,e) brk_ag_char_map_back(s, e, 15) -#define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00004000) -#define SPN_GRAPHIC_CHARS(_s) spn_ag_char_map_chars(_s, 16) -#define BRK_GRAPHIC_CHARS(_s) brk_ag_char_map_chars(_s, 16) -#define SPN_GRAPHIC_BACK(s,e) spn_ag_char_map_back(s, e, 16) -#define BRK_GRAPHIC_BACK(s,e) brk_ag_char_map_back(s, e, 16) -#define IS_INVERSION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00008000) -#define SPN_INVERSION_CHARS(_s) spn_ag_char_map_chars(_s, 17) -#define BRK_INVERSION_CHARS(_s) brk_ag_char_map_chars(_s, 17) -#define SPN_INVERSION_BACK(s,e) spn_ag_char_map_back(s, e, 17) -#define BRK_INVERSION_BACK(s,e) brk_ag_char_map_back(s, e, 17) -#define IS_OCT_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00010000) -#define SPN_OCT_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 18) -#define BRK_OCT_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 18) -#define SPN_OCT_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 18) -#define BRK_OCT_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 18) -#define IS_DEC_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00030000) -#define SPN_DEC_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 19) -#define BRK_DEC_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 19) -#define SPN_DEC_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 19) -#define BRK_DEC_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 19) -#define IS_HEX_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00070000) -#define SPN_HEX_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 20) -#define BRK_HEX_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 20) -#define SPN_HEX_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 20) -#define BRK_HEX_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 20) -#define IS_LOWER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00080000) -#define SPN_LOWER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 21) -#define BRK_LOWER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 21) -#define SPN_LOWER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 21) -#define BRK_LOWER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 21) -#define IS_UPPER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00100000) -#define SPN_UPPER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 22) -#define BRK_UPPER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 22) -#define SPN_UPPER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 22) -#define BRK_UPPER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 22) -#define IS_ALPHABETIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180000) -#define SPN_ALPHABETIC_CHARS(_s) spn_ag_char_map_chars(_s, 23) -#define BRK_ALPHABETIC_CHARS(_s) brk_ag_char_map_chars(_s, 23) -#define SPN_ALPHABETIC_BACK(s,e) spn_ag_char_map_back(s, e, 23) -#define BRK_ALPHABETIC_BACK(s,e) brk_ag_char_map_back(s, e, 23) -#define IS_ALPHANUMERIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0000) -#define SPN_ALPHANUMERIC_CHARS(_s) spn_ag_char_map_chars(_s, 24) -#define BRK_ALPHANUMERIC_CHARS(_s) brk_ag_char_map_chars(_s, 24) -#define SPN_ALPHANUMERIC_BACK(s,e) spn_ag_char_map_back(s, e, 24) -#define BRK_ALPHANUMERIC_BACK(s,e) brk_ag_char_map_back(s, e, 24) -#define IS_VAR_FIRST_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180040) -#define SPN_VAR_FIRST_CHARS(_s) spn_ag_char_map_chars(_s, 25) -#define BRK_VAR_FIRST_CHARS(_s) brk_ag_char_map_chars(_s, 25) -#define SPN_VAR_FIRST_BACK(s,e) spn_ag_char_map_back(s, e, 25) -#define BRK_VAR_FIRST_BACK(s,e) brk_ag_char_map_back(s, e, 25) -#define IS_VARIABLE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0040) -#define SPN_VARIABLE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 26) -#define BRK_VARIABLE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 26) -#define SPN_VARIABLE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 26) -#define BRK_VARIABLE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 26) -#define IS_OPTION_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0040) -#define SPN_OPTION_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 27) -#define BRK_OPTION_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 27) -#define SPN_OPTION_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 27) -#define BRK_OPTION_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 27) -#define IS_VALUE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0060) -#define SPN_VALUE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 28) -#define BRK_VALUE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 28) -#define SPN_VALUE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 28) -#define BRK_VALUE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 28) -#define IS_NAME_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00400000) -#define SPN_NAME_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 29) -#define BRK_NAME_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 29) -#define SPN_NAME_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 29) -#define BRK_NAME_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 29) -#define IS_COMPOUND_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x007B0460) -#define SPN_COMPOUND_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 30) -#define BRK_COMPOUND_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 30) -#define SPN_COMPOUND_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 30) -#define BRK_COMPOUND_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 30) -#define IS_SCHEME_NOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00003000) -#define SPN_SCHEME_NOTE_CHARS(_s) spn_ag_char_map_chars(_s, 31) -#define BRK_SCHEME_NOTE_CHARS(_s) brk_ag_char_map_chars(_s, 31) -#define SPN_SCHEME_NOTE_BACK(s,e) spn_ag_char_map_back(s, e, 31) -#define BRK_SCHEME_NOTE_BACK(s,e) brk_ag_char_map_back(s, e, 31) -#define IS_UNQUOTABLE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00800000) -#define SPN_UNQUOTABLE_CHARS(_s) spn_ag_char_map_chars(_s, 32) -#define BRK_UNQUOTABLE_CHARS(_s) brk_ag_char_map_chars(_s, 32) -#define SPN_UNQUOTABLE_BACK(s,e) spn_ag_char_map_back(s, e, 32) -#define BRK_UNQUOTABLE_BACK(s,e) brk_ag_char_map_back(s, e, 32) -#define IS_END_XML_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x01000C01) -#define SPN_END_XML_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 33) -#define BRK_END_XML_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 33) -#define SPN_END_XML_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 33) -#define BRK_END_XML_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 33) -#define IS_PLUS_N_SPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C81) -#define SPN_PLUS_N_SPACE_CHARS(_s) spn_ag_char_map_chars(_s, 34) -#define BRK_PLUS_N_SPACE_CHARS(_s) brk_ag_char_map_chars(_s, 34) -#define SPN_PLUS_N_SPACE_BACK(s,e) spn_ag_char_map_back(s, e, 34) -#define BRK_PLUS_N_SPACE_BACK(s,e) brk_ag_char_map_back(s, e, 34) -#define IS_PUNCTUATION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x02000000) -#define SPN_PUNCTUATION_CHARS(_s) spn_ag_char_map_chars(_s, 35) -#define BRK_PUNCTUATION_CHARS(_s) brk_ag_char_map_chars(_s, 35) -#define SPN_PUNCTUATION_BACK(s,e) spn_ag_char_map_back(s, e, 35) -#define BRK_PUNCTUATION_BACK(s,e) brk_ag_char_map_back(s, e, 35) -#define IS_SUFFIX_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0000) -#define SPN_SUFFIX_CHARS(_s) spn_ag_char_map_chars(_s, 36) -#define BRK_SUFFIX_CHARS(_s) brk_ag_char_map_chars(_s, 36) -#define SPN_SUFFIX_BACK(s,e) spn_ag_char_map_back(s, e, 36) -#define BRK_SUFFIX_BACK(s,e) brk_ag_char_map_back(s, e, 36) -#define IS_SUFFIX_FMT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B000C) -#define SPN_SUFFIX_FMT_CHARS(_s) spn_ag_char_map_chars(_s, 37) -#define BRK_SUFFIX_FMT_CHARS(_s) brk_ag_char_map_chars(_s, 37) -#define SPN_SUFFIX_FMT_BACK(s,e) spn_ag_char_map_back(s, e, 37) -#define BRK_SUFFIX_FMT_BACK(s,e) brk_ag_char_map_back(s, e, 37) -#define IS_FALSE_TYPE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x08000002) -#define SPN_FALSE_TYPE_CHARS(_s) spn_ag_char_map_chars(_s, 38) -#define BRK_FALSE_TYPE_CHARS(_s) brk_ag_char_map_chars(_s, 38) -#define SPN_FALSE_TYPE_BACK(s,e) spn_ag_char_map_back(s, e, 38) -#define BRK_FALSE_TYPE_BACK(s,e) brk_ag_char_map_back(s, e, 38) -#define IS_FILE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0004) -#define SPN_FILE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 39) -#define BRK_FILE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 39) -#define SPN_FILE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 39) -#define BRK_FILE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 39) -#define IS_END_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C03) -#define SPN_END_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 40) -#define BRK_END_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 40) -#define SPN_END_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 40) -#define BRK_END_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 40) -#define IS_END_LIST_ENTRY_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C13) -#define SPN_END_LIST_ENTRY_CHARS(_s) spn_ag_char_map_chars(_s, 41) -#define BRK_END_LIST_ENTRY_CHARS(_s) brk_ag_char_map_chars(_s, 41) -#define SPN_END_LIST_ENTRY_BACK(s,e) spn_ag_char_map_back(s, e, 41) -#define BRK_END_LIST_ENTRY_BACK(s,e) brk_ag_char_map_back(s, e, 41) -#define IS_SET_SEPARATOR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x10000C13) -#define SPN_SET_SEPARATOR_CHARS(_s) spn_ag_char_map_chars(_s, 42) -#define BRK_SET_SEPARATOR_CHARS(_s) brk_ag_char_map_chars(_s, 42) -#define SPN_SET_SEPARATOR_BACK(s,e) spn_ag_char_map_back(s, e, 42) -#define BRK_SET_SEPARATOR_BACK(s,e) brk_ag_char_map_back(s, e, 42) -#define IS_SIGNED_NUMBER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00038000) -#define SPN_SIGNED_NUMBER_CHARS(_s) spn_ag_char_map_chars(_s, 43) -#define BRK_SIGNED_NUMBER_CHARS(_s) brk_ag_char_map_chars(_s, 43) -#define SPN_SIGNED_NUMBER_BACK(s,e) spn_ag_char_map_back(s, e, 43) -#define BRK_SIGNED_NUMBER_BACK(s,e) brk_ag_char_map_back(s, e, 43) -#define IS_MAKE_SCRIPT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000101) -#define SPN_MAKE_SCRIPT_CHARS(_s) spn_ag_char_map_chars(_s, 44) -#define BRK_MAKE_SCRIPT_CHARS(_s) brk_ag_char_map_chars(_s, 44) -#define SPN_MAKE_SCRIPT_BACK(s,e) spn_ag_char_map_back(s, e, 44) -#define BRK_MAKE_SCRIPT_BACK(s,e) brk_ag_char_map_back(s, e, 44) -#define IS_LOAD_LINE_SKIP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000600) -#define SPN_LOAD_LINE_SKIP_CHARS(_s) spn_ag_char_map_chars(_s, 45) -#define BRK_LOAD_LINE_SKIP_CHARS(_s) brk_ag_char_map_chars(_s, 45) -#define SPN_LOAD_LINE_SKIP_BACK(s,e) spn_ag_char_map_back(s, e, 45) -#define BRK_LOAD_LINE_SKIP_BACK(s,e) brk_ag_char_map_back(s, e, 45) - -static ag_char_map_mask_t const ag_char_map_table[128] = { - /*NUL*/ 0x00000002, /*x01*/ 0x00000000, /*x02*/ 0x00000000, /*x03*/ 0x00000000, - /*x04*/ 0x00000000, /*x05*/ 0x00000000, /*x06*/ 0x00000000, /*BEL*/ 0x00000000, - /* BS*/ 0x00000800, /* HT*/ 0x00000400, /* NL*/ 0x00000001, /* VT*/ 0x00000800, - /* FF*/ 0x00000800, /* CR*/ 0x00000800, /*x0E*/ 0x00000000, /*x0F*/ 0x00000000, - /*x10*/ 0x00000000, /*x11*/ 0x00000000, /*x12*/ 0x00000000, /*x13*/ 0x00000000, - /*x14*/ 0x00000000, /*x15*/ 0x00000000, /*x16*/ 0x00000000, /*x17*/ 0x00000000, - /*x18*/ 0x00000000, /*x19*/ 0x00000000, /*x1A*/ 0x00000000, /*ESC*/ 0x00000000, - /*x1C*/ 0x00000000, /*x1D*/ 0x00000000, /*x1E*/ 0x00000000, /*x1F*/ 0x00000000, - /* */ 0x00000400, /* ! */ 0x02804000, /* " */ 0x02005000, /* # */ 0x02004000, - /* $ */ 0x02804100, /* % */ 0x02804008, /* & */ 0x02804000, /* ' */ 0x02005000, - /* ( */ 0x02006000, /* ) */ 0x02006000, /* * */ 0x02004000, /* + */ 0x12804080, - /* , */ 0x02004010, /* - */ 0x06A0C200, /* . */ 0x06C04000, /* / */ 0x03804004, - /* 0 */ 0x08814000, /* 1 */ 0x00814000, /* 2 */ 0x00814000, /* 3 */ 0x00814000, - /* 4 */ 0x00814000, /* 5 */ 0x00814000, /* 6 */ 0x00814000, /* 7 */ 0x00814000, - /* 8 */ 0x00824000, /* 9 */ 0x00824000, /* : */ 0x02804020, /* ; */ 0x02004000, - /* < */ 0x02004000, /* = */ 0x02004000, /* > */ 0x03004000, /* ? */ 0x02004000, - /* @ */ 0x02804000, /* A */ 0x00944000, /* B */ 0x00944000, /* C */ 0x00944000, - /* D */ 0x00944000, /* E */ 0x00944000, /* F */ 0x08944000, /* G */ 0x00904000, - /* H */ 0x00904000, /* I */ 0x00904000, /* J */ 0x00904000, /* K */ 0x00904000, - /* L */ 0x00904000, /* M */ 0x00904000, /* N */ 0x08904000, /* O */ 0x00904000, - /* P */ 0x00904000, /* Q */ 0x00904000, /* R */ 0x00904000, /* S */ 0x00904000, - /* T */ 0x00904000, /* U */ 0x00904000, /* V */ 0x00904000, /* W */ 0x00904000, - /* X */ 0x00904000, /* Y */ 0x00904000, /* Z */ 0x00904000, /* [ */ 0x02404000, - /* \ */ 0x02004004, /* ] */ 0x02404000, /* ^ */ 0x02A04000, /* _ */ 0x04804040, - /* ` */ 0x02004000, /* a */ 0x008C4000, /* b */ 0x008C4000, /* c */ 0x008C4000, - /* d */ 0x008C4000, /* e */ 0x008C4000, /* f */ 0x088C4000, /* g */ 0x00884000, - /* h */ 0x00884000, /* i */ 0x00884000, /* j */ 0x00884000, /* k */ 0x00884000, - /* l */ 0x00884000, /* m */ 0x00884000, /* n */ 0x08884000, /* o */ 0x00884000, - /* p */ 0x00884000, /* q */ 0x00884000, /* r */ 0x00884000, /* s */ 0x00884000, - /* t */ 0x00884000, /* u */ 0x00884000, /* v */ 0x00884000, /* w */ 0x00884000, - /* x */ 0x00884000, /* y */ 0x00884000, /* z */ 0x00884000, /* { */ 0x02004000, - /* | */ 0x12804000, /* } */ 0x02004000, /* ~ */ 0x0280C000, /*x7F*/ 0x00000000 -}; - -#include -#include -#include - -#ifndef _ -# define _(_s) _s -#endif - -static unsigned char const * ag_char_map_spanners[46]; -/** - * Character category masks. Some categories may have multiple bits, - * if their definition incorporates other character categories. - * This mask array is only used by calc_ag_char_map_spanners(). - */ -static ag_char_map_mask_t const ag_char_map_masks[46] = { - 0x00000001, /* NEWLINE */ - 0x00000002, /* NUL_BYTE */ - 0x00000004, /* DIR_SEP */ - 0x00000008, /* PERCENT */ - 0x00000010, /* COMMA */ - 0x00000020, /* COLON */ - 0x00000040, /* UNDERSCORE */ - 0x00000080, /* PLUS */ - 0x00000100, /* DOLLAR */ - 0x00000200, /* OPTION_MARKER */ - 0x00000400, /* HORIZ_WHITE */ - 0x00000800, /* ALT_WHITE */ - 0x00000C01, /* WHITESPACE */ - 0x00000C00, /* NON_NL_WHITE */ - 0x00001000, /* QUOTE */ - 0x00002000, /* PARENTHESES */ - 0x00004000, /* GRAPHIC */ - 0x00008000, /* INVERSION */ - 0x00010000, /* OCT_DIGIT */ - 0x00030000, /* DEC_DIGIT */ - 0x00070000, /* HEX_DIGIT */ - 0x00080000, /* LOWER_CASE */ - 0x00100000, /* UPPER_CASE */ - 0x00180000, /* ALPHABETIC */ - 0x001B0000, /* ALPHANUMERIC */ - 0x00180040, /* VAR_FIRST */ - 0x001B0040, /* VARIABLE_NAME */ - 0x003B0040, /* OPTION_NAME */ - 0x003B0060, /* VALUE_NAME */ - 0x00400000, /* NAME_SEP */ - 0x007B0460, /* COMPOUND_NAME */ - 0x00003000, /* SCHEME_NOTE */ - 0x00800000, /* UNQUOTABLE */ - 0x01000C01, /* END_XML_TOKEN */ - 0x00000C81, /* PLUS_N_SPACE */ - 0x02000000, /* PUNCTUATION */ - 0x041B0000, /* SUFFIX */ - 0x041B000C, /* SUFFIX_FMT */ - 0x08000002, /* FALSE_TYPE */ - 0x041B0004, /* FILE_NAME */ - 0x00000C03, /* END_TOKEN */ - 0x00000C13, /* END_LIST_ENTRY */ - 0x10000C13, /* SET_SEPARATOR */ - 0x00038000, /* SIGNED_NUMBER */ - 0x00000101, /* MAKE_SCRIPT */ - 0x00000600, /* LOAD_LINE_SKIP */ -}; -#undef LOCK_SPANNER_TABLES - -static unsigned char const * -calc_ag_char_map_spanners(unsigned int mask_ix) -{ -#ifdef LOCK_SPANNER_TABLES - if (ag_char_map_spanners[mask_ix] != NULL) - return ag_char_map_spanners[mask_ix]; - - pthread_mutex_lock(&ag_char_map_mutex); - if (ag_char_map_spanners[mask_ix] == NULL) -#endif - { - int ix = 1; - ag_char_map_mask_t mask = ag_char_map_masks[mask_ix]; - unsigned char * res = malloc(256 /* 1 << NBBY */); - if (res == NULL) { - fputs(_("no memory for char-mapper span map\n"), stderr); - exit(EXIT_FAILURE); - } - - memset(res, 0, 256); - for (; ix < 128; ix++) - if (ag_char_map_table[ix] & mask) - res[ix] = 1; - ag_char_map_spanners[mask_ix] = res; - } -#ifdef LOCK_SPANNER_TABLES - pthread_mutex_unlock(&ag_char_map_mutex); -#endif - return ag_char_map_spanners[mask_ix]; -} -#define ag_char_map_masks POISONED_ag_char_map_masks - -static inline int -is_ag_char_map_char(char ch, ag_char_map_mask_t mask) -{ - unsigned int ix = (unsigned char)ch; - return ((ix < 128) && ((ag_char_map_table[ix] & mask) != 0)); -} - -static inline char * -spn_ag_char_map_chars(char const * p, unsigned int mask_ix) -{ - unsigned char const * v = ag_char_map_spanners[mask_ix]; - if (v == NULL) - v = calc_ag_char_map_spanners(mask_ix); - while (v[(unsigned char)*p]) p++; - return (char *)(uintptr_t)p; -} - -static inline char * -brk_ag_char_map_chars(char const * p, unsigned int mask_ix) -{ - unsigned char const * v = ag_char_map_spanners[mask_ix]; - if (v == NULL) - v = calc_ag_char_map_spanners(mask_ix); - while ((*p != '\0') && (! v[(unsigned char)*p])) p++; - return (char *)(uintptr_t)p; -} - -static inline char * -spn_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) -{ - unsigned char const * v = ag_char_map_spanners[mask_ix]; - if (v == NULL) - v = calc_ag_char_map_spanners(mask_ix); - if (s >= e) e = s + strlen(s); - while ((e > s) && v[(unsigned char)e[-1]]) e--; - return (char *)(uintptr_t)e; -} - -static inline char * -brk_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) -{ - unsigned char const * v = ag_char_map_spanners[mask_ix]; - if (v == NULL) - v = calc_ag_char_map_spanners(mask_ix); - if (s == e) e += strlen(e); - while ((e > s) && (! v[(unsigned char)e[-1]])) e--; - return (char *)(uintptr_t)e; -} -#endif /* AG_CHAR_MAP_H_GUARD */ diff --git a/src/libopts/alias.c b/src/libopts/alias.c deleted file mode 100644 index 231f275..0000000 --- a/src/libopts/alias.c +++ /dev/null @@ -1,116 +0,0 @@ - -/** - * \file alias.c - * - * Handle options that are aliases for another option. - * - * @addtogroup autoopts - * @{ - */ -/* - * This routine will forward an option alias to the correct option code. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -static tSuccess -too_many_occurrences(tOptions * opts, tOptDesc * od) -{ - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { - char const * eqv = (od->optEquivIndex != NO_EQUIVALENT) ? zequiv : zNil; - - fprintf(stderr, ztoo_often_fmt, opts->pzProgName); - - if (od->optMaxCt > 1) - fprintf(stderr, zat_most, od->optMaxCt, od->pz_Name, eqv); - else - fprintf(stderr, zonly_one, od->pz_Name, eqv); - (*opts->pUsageProc)(opts, EXIT_FAILURE); - /* NOTREACHED */ - } - - return FAILURE; -} - -/*=export_func optionAlias - * private: - * - * what: relay an option to its alias - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + old_od + the descriptor for this arg + - * arg: + unsigned int + alias + the aliased-to option index + - * ret-type: int - * - * doc: - * Handle one option as if it had been specified as another. Exactly. - * Returns "-1" if the aliased-to option has appeared too many times. -=*/ -int -optionAlias(tOptions * opts, tOptDesc * old_od, unsigned int alias) -{ - tOptDesc * new_od; - - if (opts <= OPTPROC_EMIT_LIMIT) - return 0; - - new_od = opts->pOptDesc + alias; - if ((unsigned)opts->optCt <= alias) { - fputs(zbad_alias_id, stderr); - option_exits(EXIT_FAILURE); - } - - /* - * Copy over the option instance flags - */ - new_od->fOptState &= OPTST_PERSISTENT_MASK; - new_od->fOptState |= (old_od->fOptState & ~OPTST_PERSISTENT_MASK); - new_od->optArg.argString = old_od->optArg.argString; - - /* - * Keep track of count only for DEFINED (command line) options. - * IF we have too many, build up an error message and bail. - */ - if ( (new_od->fOptState & OPTST_DEFINED) - && (++new_od->optOccCt > new_od->optMaxCt) ) - return too_many_occurrences(opts, new_od); - - /* - * Clear the state bits and counters - */ - old_od->fOptState &= OPTST_PERSISTENT_MASK; - old_od->optOccCt = 0; - - /* - * If there is a procedure to call, call it - */ - if (new_od->pOptProc != NULL) - (*new_od->pOptProc)(opts, new_od); - return 0; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/alias.c */ diff --git a/src/libopts/ao-strs.c b/src/libopts/ao-strs.c deleted file mode 100644 index 7f59372..0000000 --- a/src/libopts/ao-strs.c +++ /dev/null @@ -1,379 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (ao-strs.c) - * - * It has been AutoGen-ed - * From the definitions ao-strs.def - * and the template file strings - * - * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. - * This is free software. It is licensed for use, modification and - * redistribution under the terms of the - * Modified (3 clause) Berkeley Software Distribution License - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * strings IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - */ -#include "ao-strs.h" - -char const ao_strs_strtable[6714] = -/* 0 */ "-_^\0" -/* 4 */ " %s%s\n\0" -/* 12 */ "\n\0" -/* 64 */ "\n" - "%s\n\n\0" -/* 70 */ "=file\0" -/* 76 */ "=Mbr\0" -/* 81 */ "=Cplx\0" -/* 87 */ "[=arg]\0" -/* 94 */ "--%2$s%1$s\0" -/* 105 */ "=Tim\0" -/* 110 */ "none\0" -/* 115 */ "# preset/initialization file\n" - "# %s#\n\0" -/* 153 */ " %3s %-14s %s\0" -/* 167 */ "%s\0" -/* 170 */ "T/F\0" -/* 174 */ "\n" - "%s\n\n" - "%s\0" -/* 182 */ "Fil\0" -/* 186 */ "KWd\0" -/* 190 */ "Mbr\0" -/* 194 */ "Cpx\0" -/* 198 */ "no \0" -/* 202 */ "Num\0" -/* 206 */ "opt\0" -/* 210 */ "YES\0" -/* 214 */ "Str\0" -/* 218 */ "Tim\0" -/* 222 */ "\t\t\t\t- \0" -/* 229 */ "\t\t\t\t \0" -/* 236 */ "\t\t\t\t-- and \0" -/* 248 */ "\t\t\t\t%s\n\0" -/* 256 */ " \0" -/* 263 */ " \0" -/* 269 */ " \0" -/* 273 */ " \0" -/* 276 */ "all\0" -/* 280 */ " \t\n" - ":=\0" -/* 286 */ "%s_%s_%d=\0" -/* 296 */ "''\0" -/* 299 */ " ;;\n\n\0" -/* 312 */ "'\n\n\0" -/* 316 */ "\n\0" -/* 323 */ " %s\n\0" -/* 329 */ "%%-%ds\0" -/* 336 */ "\n" - "export %s_%s_%d\n\0" -/* 354 */ "false\0" -/* 360 */ " -* )\n\0" -/* 370 */ "flag\0" -/* 375 */ "INVALID-%d\0" -/* 386 */ "*INVALID*\0" -/* 396 */ "\\n\\\n\0" -/* 401 */ " --* )\n\0" -/* 412 */ "--\0" -/* 415 */ "LONGUSAGE\0" -/* 425 */ " %s\n\0" -/* 441 */ "\\%03o\0" -/* 447 */ "more\0" -/* 452 */ "<%s type=nested>\n\0" -/* 470 */ "%s\n\0" -/* 474 */ "%s\n" - " \0" -/* 480 */ "OPT_ARG_NEEDED=NO\0" -/* 498 */ "<%s/>\n\0" -/* 505 */ "OPT_ARG_NEEDED=OK\0" -/* 523 */ "\t\0" -/* 525 */ "<%s>\0" -/* 530 */ "option\0" -/* 537 */ "\n" - "export %s_%s\n\0" -/* 552 */ "%s_%s=\0" -/* 559 */ " | \0" -/* 563 */ "PAGER\0" -/* 569 */ "%1$s %2$s ; rm -f %2$s\0" -/* 592 */ " + \0" -/* 596 */ " puts(_(%s));\n\0" -/* 612 */ "\\'\0" -/* 615 */ "'%s'\0" -/* 620 */ " -- %s\0" -/* 627 */ "%s_%s_TEXT='\0" -/* 640 */ "#! %s\n\0" -/* 647 */ "\n" - "env | grep '^%s_'\n\0" -/* 667 */ "=%1$lu # 0x%1$lX\n\0" -/* 685 */ "stdout\0" -/* 692 */ "%A %B %e, %Y at %r %Z\0" -/* 714 */ "TMPDIR\0" -/* 721 */ "%s/use-%u.XXXXXX\0" -/* 738 */ "true\0" -/* 743 */ "<%s type=%s>\0" -/* 756 */ "VERSION\0" -/* 764 */ "#x%02X;\0" -/* 772 */ "OPT_ARG_NEEDED=YES\0" -/* 791 */ "\n" - "# %s -- %s\n\0" -/* 804 */ "# DEFAULT: \0" -/* 816 */ "'\\''\0" -/* 821 */ " '%s'\0" -/* 827 */ "libopts misguessed length of string\n\0" -/* 864 */ "\n" - "OPTION_CT=0\n\0" -/* 878 */ "set --\0" -/* 885 */ "/tmp\0" -/* 890 */ " ;;\n\n\0" -/* 907 */ " '%c' )\n\0" -/* 923 */ " '%s' )\n\0" -/* 939 */ " '%s' | \\\n\0" -/* 957 */ "<%1$s type=boolean>%2$s\n\0" -/* 989 */ "# From the %s option definitions\n" - "#\n\0" -/* 1026 */ "echo 'Warning: Cannot load options files' >&2\0" -/* 1073 */ "echo 'Warning: Cannot save options files' >&2\0" -/* 1120 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0" -/* 1186 */ "<%1$s type=integer>0x%2$lX\n\0" -/* 1221 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0" -/* 1252 */ "%1$s_%2$s_MODE='%3$s'\n" - "export %1$s_%2$s_MODE\n\0" -/* 1297 */ "%1$s_%2$s='%3$s'\n" - "export %1$s_%2$s\n\0" -/* 1332 */ "%1$s_%2$s_CT=%3$d\n" - "export %1$s_%2$s_CT\n\0" -/* 1371 */ "OPTION_CT=%d\n" - "export OPTION_CT\n\0" -/* 1402 */ "%1$s_%2$s=%3$s\n" - "export %1$s_%2$s\n\0" -/* 1435 */ "%1$s_%2$s=%3$d # 0x%3$X\n" - "export %1$s_%2$s\n\0" -/* 1477 */ " case \"${OPT_CODE}\" in\n\0" -/* 1508 */ " if [ $%1$s_%2$s_CT -gt %3$u ] ; then\n" - " echo 'Error: more than %3$d %2$s options'\n" - " echo \"$%1$s_USAGE_TEXT\"\n" - " exit 1\n" - " fi >&2\n\0" -/* 1699 */ "test ${%1$s_%2$s_CT-0} -ge %3$u || {\n" - " echo %1$s_%2$s has not been set\n" - " exit 1\n" - "} 1>&2\n\0" -/* 1791 */ "test -n \"$%1$s_%2$s\" || {\n" - " echo %1$s_%2$s has not been set\n" - " exit 1\n" - "} 1>&2\n\0" -/* 1872 */ " echo \"$%s_%s_TEXT\"\n" - " exit 0\n\0" -/* 1923 */ "\n" - "# # # # # # # # # #\n" - "#\n" - "# END OF AUTOMATED OPTION PROCESSING\n" - "#\n" - "# # # # # # # # # # -- do not modify this marker --\n\0" -/* 2039 */ " if [ -n \"${OPT_ARG_VAL}\" ]\n" - " then\n" - " eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n" - " export %1$s_${OPT_NAME}${OPT_ELEMENT}\n" - " fi\n" - "done\n" - "OPTION_COUNT=`expr $ARG_COUNT - $#`\n" - "OPERAND_COUNT=$#\n" - "unset OPT_PROCESS || :\n" - "unset OPT_ELEMENT || :\n" - "unset OPT_ARG || :\n" - "unset OPT_ARG_NEEDED || :\n" - "unset OPT_NAME || :\n" - "unset OPT_CODE || :\n" - "unset OPT_ARG_VAL || :\n\0" -/* 2418 */ " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n" - " shift\n" - " OPT_ARG=$1\n" - " case \"${OPT_CODE}\" in *=* )\n" - " OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n" - " OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\0" -/* 2669 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n" - " OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0" -/* 2786 */ "\n" - "ARG_COUNT=$#\n" - "OPT_PROCESS=true\n" - "OPT_ARG=$1\n" - "while ${OPT_PROCESS} && [ $# -gt 0 ]\n" - "do\n" - " OPT_ELEMENT=''\n" - " OPT_ARG_VAL=''\n\n" - " case \"${OPT_ARG}\" in\n" - " -- )\n" - " OPT_PROCESS=false\n" - " shift\n" - " ;;\n\0" -/* 2993 */ " case \"${OPT_ARG_NEEDED}\" in\n" - " NO )\n" - " OPT_ARG_VAL=''\n" - " ;;\n" - " YES )\n" - " if [ -z \"${OPT_ARG_VAL}\" ]\n" - " then\n" - " if [ $# -eq 0 ]\n" - " then\n" - " echo No argument provided for ${OPT_NAME} option\n" - " echo \"$%s_USAGE_TEXT\"\n" - " exit 1\n" - " fi >&2\n" - " OPT_ARG_VAL=${OPT_ARG}\n" - " shift\n" - " OPT_ARG=$1\n" - " fi\n" - " ;;\n" - " OK )\n" - " if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n" - " then\n" - " case \"${OPT_ARG}\" in -* ) ;; * )\n" - " OPT_ARG_VAL=${OPT_ARG}\n" - " shift\n" - " OPT_ARG=$1 ;; esac\n" - " fi\n" - " ;;\n" - " esac\n\0" -/* 3772 */ " %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n" - " OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n" - " OPT_NAME='%2$s'\n\0" -/* 3896 */ "\n" - "if test -z \"${%1$s_%2$s}\"\n" - "then\n" - " %1$s_%2$s_CT=0\n" - " export %1$s_%2$s_CT\n" - "else\n" - " %1$s_%2$s_CT=1\n" - " %1$s_%2$s_1=${%1$s_%2$s}\n" - " export %1$s_%2$s_CT %1$s_%2$s_1\n" - "fi\n\0" -/* 4054 */ " * )\n" - " OPT_PROCESS=false\n" - " ;;\n" - " esac\n\0" -/* 4111 */ " %1$s_%2$s_CT=0\n" - " OPT_ELEMENT=''\n" - " %1$s_%2$s='%3$s'\n" - " export %1$s_%2$s\n" - " OPT_NAME='%2$s'\n\0" -/* 4252 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" - " echo 'Error: duplicate %2$s option'\n" - " echo \"$%1$s_USAGE_TEXT\"\n" - " exit 1\n" - " fi >&2\n" - " %1$s_%2$s_set=true\n" - " %1$s_%2$s='%3$s'\n" - " export %1$s_%2$s\n" - " OPT_NAME='%2$s'\n\0" -/* 4569 */ "\n" - "ARG_COUNT=$#\n" - "OPT_ARG=$1\n" - "while [ $# -gt 0 ]\n" - "do\n" - " OPT_ELEMENT=''\n" - " OPT_ARG_VAL=''\n" - " OPT_ARG=${1}\n\0" -/* 4672 */ " case \"${OPT_ARG_NEEDED}\" in\n" - " NO )\n" - " if [ -n \"${OPT_ARG}\" ]\n" - " then\n" - " OPT_ARG=-${OPT_ARG}\n" - " else\n" - " shift\n" - " OPT_ARG=$1\n" - " fi\n" - " ;;\n" - " YES )\n" - " if [ -n \"${OPT_ARG}\" ]\n" - " then\n" - " OPT_ARG_VAL=${OPT_ARG}\n" - " else\n" - " if [ $# -eq 0 ]\n" - " then\n" - " echo No argument provided for ${OPT_NAME} option\n" - " echo \"$%s_USAGE_TEXT\"\n" - " exit 1\n" - " fi >&2\n" - " shift\n" - " OPT_ARG_VAL=$1\n" - " fi\n" - " shift\n" - " OPT_ARG=$1\n" - " ;;\n" - " OK )\n" - " if [ -n \"${OPT_ARG}\" ]\n" - " then\n" - " OPT_ARG_VAL=${OPT_ARG}\n" - " shift\n" - " OPT_ARG=$1\n" - " else\n" - " shift\n" - " if [ $# -gt 0 ]\n" - " then\n" - " case \"$1\" in -* ) ;; * )\n" - " OPT_ARG_VAL=$1\n" - " shift ;; esac\n" - " OPT_ARG=$1\n" - " fi\n" - " fi\n" - " ;;\n" - " esac\n\0" -/* 5826 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n" - " exit 0\n\0" -/* 5900 */ "%s OF %s\n" - "#\n" - "# From here to the next `-- do not modify this marker --',\n" - "# the text has been generated %s\n\0" -/* 6006 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n" - " export %1$s_%2$s${OPT_ELEMENT}\n\0" -/* 6096 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" - " echo 'Error: duplicate %2$s option'\n" - " echo \"$%1$s_USAGE_TEXT\"\n" - " exit 1\n" - " fi >&2\n" - " %1$s_%2$s_set=true\n" - " OPT_NAME='%2$s'\n\0" -/* 6355 */ "\n" - "%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n" - "%1$s_%2$s_set=false\n" - "export %1$s_%2$s\n\0" -/* 6424 */ "\n" - "%1$s_%2$s=${%1$s_%2$s}\n" - "%1$s_%2$s_set=false\n" - "export %1$s_%2$s\n\0" -/* 6486 */ "# # # # # # # # # # -- do not modify this marker --\n" - "#\n" - "# DO NOT EDIT THIS SECTION\n\0" -/* 6569 */ " * )\n" - " echo Unknown %s: \"${OPT_CODE}\" >&2\n" - " echo \"$%s_USAGE_TEXT\" >&2\n" - " exit 1\n" - " ;;\n" - " esac\n"; - -/* end of ao-strs.c */ diff --git a/src/libopts/ao-strs.h b/src/libopts/ao-strs.h deleted file mode 100644 index 95036ef..0000000 --- a/src/libopts/ao-strs.h +++ /dev/null @@ -1,338 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (ao-strs.h) - * - * It has been AutoGen-ed - * From the definitions ao-strs.def - * and the template file strings - * - * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. - * This is free software. It is licensed for use, modification and - * redistribution under the terms of the - * Modified (3 clause) Berkeley Software Distribution License - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * strings IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - */ -#ifndef STRINGS_AO_STRS_H_GUARD -#define STRINGS_AO_STRS_H_GUARD 1 -/* - * 146 strings in ao_strs_strtable string table - */ -#define ARG_BREAK_STR (ao_strs_strtable+280) -#define ARG_BREAK_STR_LEN 5 -#define ARG_BY_NUM_FMT (ao_strs_strtable+286) -#define ARG_BY_NUM_FMT_LEN 9 -#define BOOL_ATR_FMT (ao_strs_strtable+957) -#define BOOL_ATR_FMT_LEN 31 -#define CHK_MAX_COUNT (ao_strs_strtable+1508) -#define CHK_MAX_COUNT_LEN 190 -#define CHK_MIN_COUNT (ao_strs_strtable+1699) -#define CHK_MIN_COUNT_LEN 91 -#define CHK_ONE_REQUIRED (ao_strs_strtable+1791) -#define CHK_ONE_REQUIRED_LEN 80 -#define ECHO_N_EXIT (ao_strs_strtable+1872) -#define ECHO_N_EXIT_LEN 50 -#define EMPTY_ARG (ao_strs_strtable+296) -#define EMPTY_ARG_LEN 2 -#define END_MARK (ao_strs_strtable+1923) -#define END_MARK_LEN 115 -#define END_OPT_SEL_STR (ao_strs_strtable+299) -#define END_OPT_SEL_STR_LEN 12 -#define END_PRE_FMT (ao_strs_strtable+989) -#define END_PRE_FMT_LEN 36 -#define END_SET_TEXT (ao_strs_strtable+312) -#define END_SET_TEXT_LEN 3 -#define END_XML_FMT (ao_strs_strtable+316) -#define END_XML_FMT_LEN 6 -#define ENUM_ERR_LINE (ao_strs_strtable+323) -#define ENUM_ERR_LINE_LEN 5 -#define ENUM_ERR_WIDTH (ao_strs_strtable+329) -#define ENUM_ERR_WIDTH_LEN 6 -#define EXPORT_ARG_FMT (ao_strs_strtable+336) -#define EXPORT_ARG_FMT_LEN 17 -#define FALSE_STR (ao_strs_strtable+354) -#define FALSE_STR_LEN 5 -#define FINISH_LOOP (ao_strs_strtable+2039) -#define FINISH_LOOP_LEN 378 -#define FLAG_OPT_MARK (ao_strs_strtable+360) -#define FLAG_OPT_MARK_LEN 9 -#define FLAG_STR (ao_strs_strtable+370) -#define FLAG_STR_LEN 4 -#define INIT_LOPT_STR (ao_strs_strtable+2418) -#define INIT_LOPT_STR_LEN 250 -#define INIT_OPT_STR (ao_strs_strtable+2669) -#define INIT_OPT_STR_LEN 116 -#define INVALID_FMT (ao_strs_strtable+375) -#define INVALID_FMT_LEN 10 -#define INVALID_STR (ao_strs_strtable+386) -#define INVALID_STR_LEN 9 -#define LINE_SPLICE (ao_strs_strtable+396) -#define LINE_SPLICE_LEN 4 -#define LONG_OPT_MARK (ao_strs_strtable+401) -#define LONG_OPT_MARKER (ao_strs_strtable+412) -#define LONG_OPT_MARKER_LEN 2 -#define LONG_OPT_MARK_LEN 10 -#define LONG_USE_STR (ao_strs_strtable+415) -#define LONG_USE_STR_LEN 9 -#define LOOP_STR (ao_strs_strtable+2786) -#define LOOP_STR_LEN 206 -#define LOPT_ARG_FMT (ao_strs_strtable+2993) -#define LOPT_ARG_FMT_LEN 778 -#define LVL3_CMD (ao_strs_strtable+425) -#define LVL3_CMD_LEN 15 -#define MK_STR_OCT_FMT (ao_strs_strtable+441) -#define MK_STR_OCT_FMT_LEN 5 -#define MORE_STR (ao_strs_strtable+447) -#define MORE_STR_LEN 4 -#define MULTI_ARG_FMT (ao_strs_strtable+3772) -#define MULTI_ARG_FMT_LEN 123 -#define MULTI_DEF_FMT (ao_strs_strtable+3896) -#define MULTI_DEF_FMT_LEN 157 -#define NESTED_OPT_FMT (ao_strs_strtable+452) -#define NESTED_OPT_FMT_LEN 17 -#define NLSTR_FMT (ao_strs_strtable+470) -#define NLSTR_FMT_LEN 3 -#define NLSTR_SPACE_FMT (ao_strs_strtable+474) -#define NLSTR_SPACE_FMT_LEN 5 -#define NONE_STR (ao_strs_strtable+110) -#define NONE_STR_LEN 4 -#define NOT_FOUND_STR (ao_strs_strtable+4054) -#define NOT_FOUND_STR_LEN 56 -#define NO_ARG_NEEDED (ao_strs_strtable+480) -#define NO_ARG_NEEDED_LEN 17 -#define NO_LOAD_WARN (ao_strs_strtable+1026) -#define NO_LOAD_WARN_LEN 46 -#define NO_MULTI_ARG_FMT (ao_strs_strtable+4111) -#define NO_MULTI_ARG_FMT_LEN 140 -#define NO_SAVE_OPTS (ao_strs_strtable+1073) -#define NO_SAVE_OPTS_LEN 46 -#define NO_SGL_ARG_FMT (ao_strs_strtable+4252) -#define NO_SGL_ARG_FMT_LEN 316 -#define NO_SUPPRESS_LOAD (ao_strs_strtable+1120) -#define NO_SUPPRESS_LOAD_LEN 65 -#define NULL_ATR_FMT (ao_strs_strtable+498) -#define NULL_ATR_FMT_LEN 6 -#define NUMB_ATR_FMT (ao_strs_strtable+1186) -#define NUMB_ATR_FMT_LEN 34 -#define OK_NEED_OPT_ARG (ao_strs_strtable+505) -#define OK_NEED_OPT_ARG_LEN 17 -#define ONE_TAB_STR (ao_strs_strtable+523) -#define ONE_TAB_STR_LEN 1 -#define ONLY_OPTS_LOOP (ao_strs_strtable+4569) -#define ONLY_OPTS_LOOP_LEN 102 -#define OPEN_CLOSE_FMT (ao_strs_strtable+498) -#define OPEN_CLOSE_FMT_LEN 6 -#define OPEN_XML_FMT (ao_strs_strtable+525) -#define OPEN_XML_FMT_LEN 4 -#define OPTION_STR (ao_strs_strtable+530) -#define OPTION_STR_LEN 6 -#define OPT_ARG_FMT (ao_strs_strtable+4672) -#define OPT_ARG_FMT_LEN 1153 -#define OPT_END_FMT (ao_strs_strtable+537) -#define OPT_END_FMT_LEN 14 -#define OPT_VAL_FMT (ao_strs_strtable+552) -#define OPT_VAL_FMT_LEN 6 -#define OR_STR (ao_strs_strtable+559) -#define OR_STR_LEN 3 -#define PAGER_NAME (ao_strs_strtable+563) -#define PAGER_NAME_LEN 5 -#define PAGE_USAGE_FMT (ao_strs_strtable+569) -#define PAGE_USAGE_FMT_LEN 22 -#define PAGE_USAGE_TEXT (ao_strs_strtable+5826) -#define PAGE_USAGE_TEXT_LEN 73 -#define PLUS_STR (ao_strs_strtable+592) -#define PLUS_STR_LEN 3 -#define PREAMBLE_FMT (ao_strs_strtable+5900) -#define PREAMBLE_FMT_LEN 105 -#define PUTS_FMT (ao_strs_strtable+596) -#define PUTS_FMT_LEN 15 -#define QUOT_APOS (ao_strs_strtable+612) -#define QUOT_APOS_LEN 2 -#define QUOT_ARG_FMT (ao_strs_strtable+615) -#define QUOT_ARG_FMT_LEN 4 -#define SET_MULTI_ARG (ao_strs_strtable+6006) -#define SET_MULTI_ARG_LEN 89 -#define SET_NO_TEXT_FMT (ao_strs_strtable+1221) -#define SET_NO_TEXT_FMT_LEN 30 -#define SET_OFF_FMT (ao_strs_strtable+620) -#define SET_OFF_FMT_LEN 6 -#define SET_TEXT_FMT (ao_strs_strtable+627) -#define SET_TEXT_FMT_LEN 12 -#define SGL_ARG_FMT (ao_strs_strtable+6096) -#define SGL_ARG_FMT_LEN 258 -#define SGL_DEF_FMT (ao_strs_strtable+6355) -#define SGL_DEF_FMT_LEN 68 -#define SGL_NO_DEF_FMT (ao_strs_strtable+6424) -#define SGL_NO_DEF_FMT_LEN 61 -#define SHELL_MAGIC (ao_strs_strtable+640) -#define SHELL_MAGIC_LEN 6 -#define SHOW_PROG_ENV (ao_strs_strtable+647) -#define SHOW_PROG_ENV_LEN 19 -#define SHOW_VAL_FMT (ao_strs_strtable+667) -#define SHOW_VAL_FMT_LEN 17 -#define START_MARK (ao_strs_strtable+6486) -#define START_MARK_LEN 82 -#define STDOUT (ao_strs_strtable+685) -#define STDOUT_LEN 6 -#define TIME_FMT (ao_strs_strtable+692) -#define TIME_FMT_LEN 21 -#define TMPDIR (ao_strs_strtable+714) -#define TMPDIR_LEN 6 -#define TMP_FILE_FMT (ao_strs_strtable+721) -#define TMP_FILE_FMT_LEN 16 -#define TMP_USAGE_FMT (ao_strs_strtable+721) -#define TMP_USAGE_FMT_LEN 16 -#define TRUE_STR (ao_strs_strtable+738) -#define TRUE_STR_LEN 4 -#define TWO_SPACES_STR (ao_strs_strtable+273) -#define TWO_SPACES_STR_LEN 2 -#define TYPE_ATR_FMT (ao_strs_strtable+743) -#define TYPE_ATR_FMT_LEN 12 -#define UNK_OPT_FMT (ao_strs_strtable+6569) -#define UNK_OPT_FMT_LEN 144 -#define VER_STR (ao_strs_strtable+756) -#define VER_STR_LEN 7 -#define XML_HEX_BYTE_FMT (ao_strs_strtable+764) -#define XML_HEX_BYTE_FMT_LEN 7 -#define YES_NEED_OPT_ARG (ao_strs_strtable+772) -#define YES_NEED_OPT_ARG_LEN 18 -#define ao_default_use (ao_strs_strtable+804) -#define ao_default_use_LEN 11 -#define ao_name_use_fmt (ao_strs_strtable+791) -#define ao_name_use_fmt_LEN 12 -#define apostrophe (ao_strs_strtable+816) -#define apostrophe_LEN 4 -#define arg_fmt (ao_strs_strtable+821) -#define arg_fmt_LEN 5 -#define init_optct (ao_strs_strtable+864) -#define init_optct_LEN 13 -#define misguess_len (ao_strs_strtable+827) -#define misguess_len_LEN 36 -#define set_dash (ao_strs_strtable+878) -#define set_dash_LEN 6 -#define tmp_dir (ao_strs_strtable+885) -#define tmp_dir_LEN 4 -#define zAll (ao_strs_strtable+276) -#define zAll_LEN 3 -#define zCfgAO_Flags (ao_strs_strtable+12) -#define zCfgAO_Flags_LEN 14 -#define zCfgProg (ao_strs_strtable+27) -#define zCfgProg_LEN 9 -#define zEquivMode (ao_strs_strtable+1252) -#define zEquivMode_LEN 44 -#define zFiveSpaces (ao_strs_strtable+263) -#define zFiveSpaces_LEN 5 -#define zFmtFmt (ao_strs_strtable+37) -#define zFmtFmt_LEN 11 -#define zFmtProg (ao_strs_strtable+49) -#define zFmtProg_LEN 14 -#define zFullOptFmt (ao_strs_strtable+1297) -#define zFullOptFmt_LEN 34 -#define zGnuBreak (ao_strs_strtable+64) -#define zGnuBreak_LEN 5 -#define zGnuFileArg (ao_strs_strtable+70) -#define zGnuFileArg_LEN 5 -#define zGnuKeyLArg (ao_strs_strtable+76) -#define zGnuKeyLArg_LEN 4 -#define zGnuNestArg (ao_strs_strtable+81) -#define zGnuNestArg_LEN 5 -#define zGnuOptArg (ao_strs_strtable+87) -#define zGnuOptArg_LEN 6 -#define zGnuOptFmt (ao_strs_strtable+94) -#define zGnuOptFmt_LEN 10 -#define zGnuTimeArg (ao_strs_strtable+105) -#define zGnuTimeArg_LEN 4 -#define zNone (ao_strs_strtable+110) -#define zNone_LEN 4 -#define zOptCookieCt (ao_strs_strtable+1332) -#define zOptCookieCt_LEN 38 -#define zOptCtFmt (ao_strs_strtable+1371) -#define zOptCtFmt_LEN 30 -#define zOptDisabl (ao_strs_strtable+1402) -#define zOptDisabl_LEN 32 -#define zOptNumFmt (ao_strs_strtable+1435) -#define zOptNumFmt_LEN 41 -#define zOptionCase (ao_strs_strtable+1477) -#define zOptionCase_LEN 30 -#define zOptionEndSelect (ao_strs_strtable+890) -#define zOptionEndSelect_LEN 16 -#define zOptionFlag (ao_strs_strtable+907) -#define zOptionFlag_LEN 15 -#define zOptionFullName (ao_strs_strtable+923) -#define zOptionFullName_LEN 15 -#define zOptionPartName (ao_strs_strtable+939) -#define zOptionPartName_LEN 17 -#define zPresetFile (ao_strs_strtable+115) -#define zPresetFile_LEN 37 -#define zReqOptFmt (ao_strs_strtable+153) -#define zReqOptFmt_LEN 13 -#define zSepChars (ao_strs_strtable+0) -#define zSepChars_LEN 3 -#define zShrtGnuOptFmt (ao_strs_strtable+167) -#define zShrtGnuOptFmt_LEN 2 -#define zSixSpaces (ao_strs_strtable+256) -#define zSixSpaces_LEN 6 -#define zStdBoolArg (ao_strs_strtable+170) -#define zStdBoolArg_LEN 3 -#define zStdBreak (ao_strs_strtable+174) -#define zStdBreak_LEN 7 -#define zStdFileArg (ao_strs_strtable+182) -#define zStdFileArg_LEN 3 -#define zStdKeyArg (ao_strs_strtable+186) -#define zStdKeyArg_LEN 3 -#define zStdKeyLArg (ao_strs_strtable+190) -#define zStdKeyLArg_LEN 3 -#define zStdNestArg (ao_strs_strtable+194) -#define zStdNestArg_LEN 3 -#define zStdNoArg (ao_strs_strtable+198) -#define zStdNoArg_LEN 3 -#define zStdNumArg (ao_strs_strtable+202) -#define zStdNumArg_LEN 3 -#define zStdOptArg (ao_strs_strtable+206) -#define zStdOptArg_LEN 3 -#define zStdReqArg (ao_strs_strtable+210) -#define zStdReqArg_LEN 3 -#define zStdStrArg (ao_strs_strtable+214) -#define zStdStrArg_LEN 3 -#define zStdTimeArg (ao_strs_strtable+218) -#define zStdTimeArg_LEN 3 -#define zTabHyp (ao_strs_strtable+222) -#define zTabHypAnd (ao_strs_strtable+236) -#define zTabHypAnd_LEN 11 -#define zTabHyp_LEN 6 -#define zTabSpace (ao_strs_strtable+229) -#define zTabSpace_LEN 6 -#define zTabout (ao_strs_strtable+248) -#define zTabout_LEN 7 -#define zThreeSpaces (ao_strs_strtable+269) -#define zThreeSpaces_LEN 3 -#define zTwoSpaces (ao_strs_strtable+273) -#define zTwoSpaces_LEN 2 -#define zambig_file (ao_strs_strtable+4) -#define zambig_file_LEN 7 -extern char const ao_strs_strtable[6714]; - -#endif /* STRINGS_AO_STRS_H_GUARD */ diff --git a/src/libopts/autoopts.c b/src/libopts/autoopts.c deleted file mode 100644 index 643d277..0000000 --- a/src/libopts/autoopts.c +++ /dev/null @@ -1,391 +0,0 @@ - -/** - * \file autoopts.c - * - * This file contains all of the routines that must be linked into - * an executable to use the generated option processing. The optional - * routines are in separately compiled modules so that they will not - * necessarily be linked in. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * The number of tab characters to skip when printing continuation lines. - */ - static unsigned int tab_skip_ct = 0; - -#ifndef HAVE_PATHFIND -# define pathfind(_p, _n, _m) option_pathfind(_p, _n, _m) -# include "compat/pathfind.c" -#endif - -#ifndef HAVE_SNPRINTF -# define vsnprintf option_vsnprintf -# define snprintf option_snprintf -# include "compat/snprintf.c" -#endif - -#ifndef HAVE_STRDUP -# define strdup(_s) option_strdup(_s) -# include "compat/strdup.c" -#endif - -#ifndef HAVE_STRCHR -# define strrchr(_s, _c) option_strrchr(_s, _c) -# define strchr(_s, _c) option_strchr(_s, _c) -# include "compat/strchr.c" -#endif - -static void * -ao_malloc(size_t sz) -{ - void * res = malloc(sz); - if (res == NULL) { - fprintf(stderr, zalloc_fail, (int)sz); - option_exits(EXIT_FAILURE); - } - return res; -} - -static void * -ao_realloc(void *p, size_t sz) -{ - void * res = (p == NULL) ? malloc(sz) : realloc(p, sz); - if (res == NULL) { - fprintf(stderr, zrealloc_fail, (int)sz, p); - option_exits(EXIT_FAILURE); - } - return res; -} - -static char * -ao_strdup(char const *str) -{ - char * res = strdup(str); - if (res == NULL) { - fprintf(stderr, zalloc_fail, (int)strlen(str)); - option_exits(EXIT_FAILURE); - } - return res; -} - -/** - * handle an option. - * - * This routine handles equivalencing, sets the option state flags and - * invokes the handler procedure, if any. - */ -static tSuccess -handle_opt(tOptions * opts, tOptState * o_st) -{ - /* - * Save a copy of the option procedure pointer. - * If this is an equivalence class option, we still want this proc. - */ - tOptDesc * od = o_st->pOD; - tOptProc * opt_proc = od->pOptProc; - if (od->fOptState & OPTST_ALLOC_ARG) - AGFREE(od->optArg.argString); - - od->optArg.argString = o_st->pzOptArg; - - /* - * IF we are presetting options, then we will ignore any un-presettable - * options. They are the ones either marked as such. - */ - if ( ((opts->fOptSet & OPTPROC_PRESETTING) != 0) - && ((od->fOptState & OPTST_NO_INIT) != 0) - ) - return PROBLEM; - - /* - * IF this is an equivalence class option, - * THEN - * Save the option value that got us to this option - * entry. (It may not be od->optChar[0], if this is an - * equivalence entry.) - * set the pointer to the equivalence class base - */ - if (od->optEquivIndex != NO_EQUIVALENT) { - tOptDesc * eqv_od = opts->pOptDesc + od->optEquivIndex; - - /* - * IF the current option state has not been defined (set on the - * command line), THEN we will allow continued resetting of - * the value. Once "defined", then it must not change. - */ - if ((od->fOptState & OPTST_DEFINED) != 0) { - /* - * The equivalenced-to option has been found on the command - * line before. Make sure new occurrences are the same type. - * - * IF this option has been previously equivalenced and - * it was not the same equivalenced-to option, - * THEN we have a usage problem. - */ - if (eqv_od->optActualIndex != od->optIndex) { - fprintf(stderr, zmultiway_bug, eqv_od->pz_Name, od->pz_Name, - (opts->pOptDesc + eqv_od->optActualIndex)->pz_Name); - return FAILURE; - } - } else { - /* - * Set the equivalenced-to actual option index to no-equivalent - * so that we set all the entries below. This option may either - * never have been selected before, or else it was selected by - * some sort of "presetting" mechanism. - */ - eqv_od->optActualIndex = NO_EQUIVALENT; - } - - if (eqv_od->optActualIndex != od->optIndex) { - /* - * First time through, copy over the state - * and add in the equivalence flag - */ - eqv_od->optActualValue = od->optValue; - eqv_od->optActualIndex = od->optIndex; - o_st->flags |= OPTST_EQUIVALENCE; - } - - /* - * Copy the most recent option argument. set membership state - * is kept in 'eqv_od->optCookie'. Do not overwrite. - */ - eqv_od->optArg.argString = od->optArg.argString; - od = eqv_od; - - } else { - od->optActualValue = od->optValue; - od->optActualIndex = od->optIndex; - } - - od->fOptState &= OPTST_PERSISTENT_MASK; - od->fOptState |= (o_st->flags & ~OPTST_PERSISTENT_MASK); - - /* - * Keep track of count only for DEFINED (command line) options. - * IF we have too many, build up an error message and bail. - */ - if ( (od->fOptState & OPTST_DEFINED) - && (++od->optOccCt > od->optMaxCt) ) - return too_many_occurrences(opts, od); - /* - * If provided a procedure to call, call it - */ - if (opt_proc != NULL) - (*opt_proc)(opts, od); - - return SUCCESS; -} - -/** - * Find the option descriptor and option argument (if any) for the - * next command line argument. DO NOT modify the descriptor. Put - * all the state in the state argument so that the option can be skipped - * without consequence (side effect). - * - * @param opts the program option descriptor - * @param o_st the state of the next found option - */ -static tSuccess -next_opt(tOptions * opts, tOptState * o_st) -{ - { - tSuccess res = find_opt(opts, o_st); - if (! SUCCESSFUL(res)) - return res; - } - - if ( ((o_st->flags & OPTST_DEFINED) != 0) - && ((o_st->pOD->fOptState & OPTST_NO_COMMAND) != 0)) { - fprintf(stderr, zNotCmdOpt, o_st->pOD->pz_Name); - return FAILURE; - } - - return get_opt_arg(opts, o_st); -} - -/** - * Process all the options from our current position onward. (This allows - * interspersed options and arguments for the few non-standard programs that - * require it.) Thus, do not rewind option indexes because some programs - * choose to re-invoke after a non-option. - * - * @param[in,out] opts program options descriptor - * @returns SUCCESS or FAILURE - */ -static tSuccess -regular_opts(tOptions * opts) -{ - /* assert: opts->fOptSet & OPTPROC_IMMEDIATE == 0 */ - for (;;) { - tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED); - - switch (next_opt(opts, &opt_st)) { - case FAILURE: goto failed_option; - case PROBLEM: return SUCCESS; /* no more args */ - case SUCCESS: break; - } - - /* - * IF this is an immediate action option, - * THEN skip it (unless we are supposed to do it a second time). - */ - if (! DO_NORMALLY(opt_st.flags)) { - if (! DO_SECOND_TIME(opt_st.flags)) - continue; - opt_st.pOD->optOccCt--; /* don't count this repetition */ - } - - if (! SUCCESSFUL(handle_opt(opts, &opt_st))) - break; - } failed_option:; - - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - (*opts->pUsageProc)(opts, EXIT_FAILURE); - - return FAILURE; -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE - */ -/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ -/*=* - * library: opts - * header: your-opts.h - * - * lib_description: - * - * These are the routines that libopts users may call directly from their - * code. There are several other routines that can be called by code - * generated by the libopts option templates, but they are not to be - * called from any other user code. The @file{options.h} header is - * fairly clear about this, too. -=*/ - -/*=export_func optionProcess - * - * what: this is the main option processing routine - * - * arg: + tOptions * + opts + program options descriptor + - * arg: + int + a_ct + program arg count + - * arg: + char ** + a_v + program arg vector + - * - * ret_type: int - * ret_desc: the count of the arguments processed - * - * doc: - * - * This is the main entry point for processing options. It is intended - * that this procedure be called once at the beginning of the execution of - * a program. Depending on options selected earlier, it is sometimes - * necessary to stop and restart option processing, or to select completely - * different sets of options. This can be done easily, but you generally - * do not want to do this. - * - * The number of arguments processed always includes the program name. - * If one of the arguments is "--", then it is counted and the processing - * stops. If an error was encountered and errors are to be tolerated, then - * the returned value is the index of the argument causing the error. - * A hyphen by itself ("-") will also cause processing to stop and will - * @emph{not} be counted among the processed arguments. A hyphen by itself - * is treated as an operand. Encountering an operand stops option - * processing. - * - * err: Errors will cause diagnostics to be printed. @code{exit(3)} may - * or may not be called. It depends upon whether or not the options - * were generated with the "allow-errors" attribute, or if the - * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. -=*/ -int -optionProcess(tOptions * opts, int a_ct, char ** a_v) -{ - if (! SUCCESSFUL(validate_struct(opts, a_v[0]))) - ao_bug(zbad_data_msg); - - /* - * Establish the real program name, the program full path, - * and do all the presetting the first time thru only. - */ - if (! ao_initialize(opts, a_ct, a_v)) - return 0; - - /* - * IF we are (re)starting, - * THEN reset option location - */ - if (opts->curOptIdx <= 0) { - opts->curOptIdx = 1; - opts->pzCurOpt = NULL; - } - - if (! SUCCESSFUL(regular_opts(opts))) - return (int)opts->origArgCt; - - /* - * IF there were no errors - * AND we have RC/INI files - * AND there is a request to save the files - * THEN do that now before testing for conflicts. - * (conflicts are ignored in preset options) - */ - switch (opts->specOptIdx.save_opts) { - case 0: - case NO_EQUIVALENT: - break; - default: - { - tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts; - - if (SELECTED_OPT(od)) { - optionSaveFile(opts); - option_exits(EXIT_SUCCESS); - } - } - } - - /* - * IF we are checking for errors, - * THEN look for too few occurrences of required options - */ - if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - && (! is_consistent(opts))) - (*opts->pUsageProc)(opts, EXIT_FAILURE); - - return (int)opts->curOptIdx; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/autoopts.c */ diff --git a/src/libopts/autoopts.h b/src/libopts/autoopts.h deleted file mode 100644 index 36bb43f..0000000 --- a/src/libopts/autoopts.h +++ /dev/null @@ -1,494 +0,0 @@ - -/* - * \file autoopts.h - * - * This file defines all the global structures and special values - * used in the automated option processing library. - * - * @group autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -#ifndef AUTOGEN_AUTOOPTS_H -#define AUTOGEN_AUTOOPTS_H -#include - -#define AO_NAME_LIMIT 127 -#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) - -#ifndef AG_PATH_MAX -# ifdef PATH_MAX -# define AG_PATH_MAX ((size_t)PATH_MAX) -# else -# ifdef __gnu_hurd__ -# define size_t unsigned long -# endif -# define AG_PATH_MAX ((size_t)4096) -# endif -#else -# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) -# undef AG_PATH_MAX -# define AG_PATH_MAX ((size_t)PATH_MAX) -# endif -#endif - -#undef EXPORT -#define EXPORT - -#ifndef NUL -#define NUL '\0' -#endif -#define BEL '\a' -#define BS '\b' -#define HT '\t' -#define LF '\n' -#define VT '\v' -#define FF '\f' -#define CR '\r' - -#if defined(_WIN32) && !defined(__CYGWIN__) -# define DIRCH '\\' -#else -# define DIRCH '/' -#endif - -#ifndef EX_USAGE - /** - * Command line usage problem - */ -# define EX_USAGE 64 -#endif -#ifndef EX_DATAERR - /** - * The input data was incorrect in some way. - */ -# define EX_DATAERR 64 -#endif -#ifndef EX_NOINPUT - /** - * option state was requested from a file that cannot be loaded. - */ -# define EX_NOINPUT 66 -#endif -#ifndef EX_SOFTWARE - /** - * AutoOpts Software failure. - */ -# define EX_SOFTWARE 70 -#endif -#ifndef EX_OSERR - /** - * Command line usage problem - */ -# define EX_OSERR 71 -#endif - -#define NL '\n' -#ifndef C -/** - * Coercive cast. Compel an address to be interpreted as the type - * of the first argument. No complaints, just do it. - */ -#define C(_t,_p) ((_t)VOIDP(_p)) -#endif - -/* The __attribute__((__warn_unused_result__)) feature - is available in gcc versions 3.4 and newer, - while the typeof feature has been available since 2.7 at least. */ -# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) -# define ignore_val(x) ((void) (x)) -# else -# define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; })) -# endif - -/* - * Convert the number to a list usable in a printf call - */ -#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F - -#define NAMED_OPTS(po) \ - (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) - -#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0) - -typedef int tDirection; -/** - * handling option presets. Start with command line and work through - * config settings in reverse order. - */ -#define DIRECTION_PRESET -1 -/** - * handling normal options. Start with first config file, then environment - * variables and finally the command line. - */ -#define DIRECTION_PROCESS 1 -/** - * An initialzation phase or an option being loaded from program sources. - */ -#define DIRECTION_CALLED 0 - -#define PROCESSING(d) ((d)>0) -#define PRESETTING(d) ((d)<0) -#define CALLED(d) ((d)==0) - -/** - * When loading a line (or block) of text as an option, the value can - * be processed in any of several modes. - */ -typedef enum { - /** - * If the value looks like a quoted string, then process it. Double - * quoted strings are processed the way strings are in "C" programs, - * except they are treated as regular characters if the following - * character is not a well-established escape sequence. Single quoted - * strings (quoted with apostrophies) are handled the way strings are - * handled in shell scripts, *except* that backslash escapes are - * honored before backslash escapes and apostrophies. - */ - OPTION_LOAD_COOKED, - - /** - * Even if the value begins with quote characters, do not do quote - * processing. Strip leading and trailing white space. - */ - OPTION_LOAD_UNCOOKED, - - /** - * Keep every part of the value between the delimiters. - */ - OPTION_LOAD_KEEP -} tOptionLoadMode; - -static tOptionLoadMode option_load_mode; - -/** - * The pager state is used by optionPagedUsage() procedure. - * When it runs, it sets itself up to be called again on exit. - * If, however, a routine needs a child process to do some work - * before it is done, then 'pagerState' must be set to - * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try - * to run the pager program before its time. - */ -typedef enum { - PAGER_STATE_INITIAL, //@< initial option paging state - - /** - * temp file created and optionPagedUsage is scheduled to run at exit - */ - PAGER_STATE_READY, - - /** - * This is a child process used in creating shell script usage. - */ - PAGER_STATE_CHILD -} tePagerState; - -typedef enum { - ENV_ALL, - ENV_IMM, - ENV_NON_IMM -} teEnvPresetType; - -typedef enum { - TOPT_UNDEFINED = 0, - TOPT_SHORT, - TOPT_LONG, - TOPT_DEFAULT -} teOptType; - -typedef struct { - tOptDesc * pOD; - char const * pzOptArg; - opt_state_mask_t flags; - teOptType optType; -} tOptState; -#define OPTSTATE_INITIALIZER(st) \ - { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } - -#define TEXTTO_TABLE \ - _TT_(LONGUSAGE) \ - _TT_(USAGE) \ - _TT_(VERSION) -#define _TT_(n) \ - TT_ ## n , - -typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; - -#undef _TT_ - -/** - * option argument types. Used to create usage information for - * particular options. - */ -typedef struct { - char const * pzStr; - char const * pzReq; - char const * pzNum; - char const * pzFile; - char const * pzKey; - char const * pzKeyL; - char const * pzBool; - char const * pzNest; - char const * pzOpt; - char const * pzNo; - char const * pzBrk; - char const * pzNoF; - char const * pzSpc; - char const * pzOptFmt; - char const * pzTime; -} arg_types_t; - -#define AGALOC(_c, _w) ao_malloc((size_t)_c) -#define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c) -#define AGFREE(_p) free(VOIDP(_p)) -#define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s)) - -static void * -ao_malloc(size_t sz); - -static void * -ao_realloc(void *p, size_t sz); - -#define ao_free(_p) free(VOIDP(_p)) - -static char * -ao_strdup(char const * str); - -/** - * DO option handling? - * - * Options are examined at two times: at immediate handling time and at - * normal handling time. If an option is disabled, the timing may be - * different from the handling of the undisabled option. The OPTST_DIABLED - * bit indicates the state of the currently discovered option. - * So, here's how it works: - * - * A) handling at "immediate" time, either 1 or 2: - * - * 1. OPTST_DISABLED is not set: - * IMM must be set - * DISABLE_IMM don't care - * TWICE don't care - * DISABLE_TWICE don't care - * 0 -and- 1 x x x - * - * 2. OPTST_DISABLED is set: - * IMM don't care - * DISABLE_IMM must be set - * TWICE don't care - * DISABLE_TWICE don't care - * 1 -and- x 1 x x - */ -#define DO_IMMEDIATELY(_flg) \ - ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ - || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ - == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) - -/** - * B) handling at "regular" time because it was not immediate - * - * 1. OPTST_DISABLED is not set: - * IMM must *NOT* be set - * DISABLE_IMM don't care - * TWICE don't care - * DISABLE_TWICE don't care - * 0 -and- 0 x x x - * - * 2. OPTST_DISABLED is set: - * IMM don't care - * DISABLE_IMM don't care - * TWICE must be set - * DISABLE_TWICE don't care - * 1 -and- x x 1 x - */ -#define DO_NORMALLY(_flg) ( \ - (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ - || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ - OPTST_DISABLED) ) - -/** - * C) handling at "regular" time because it is to be handled twice. - * The immediate bit was already tested and found to be set: - * - * 3. OPTST_DISABLED is not set: - * IMM is set (but don't care) - * DISABLE_IMM don't care - * TWICE must be set - * DISABLE_TWICE don't care - * 0 -and- ? x 1 x - * - * 4. OPTST_DISABLED is set: - * IMM don't care - * DISABLE_IMM is set (but don't care) - * TWICE don't care - * DISABLE_TWICE must be set - * 1 -and- x ? x 1 - */ -#define DO_SECOND_TIME(_flg) ( \ - (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ - OPTST_TWICE) \ - || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ - (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) - -/* - * text_mmap structure. Only active on platforms with mmap(2). - */ -#ifdef HAVE_SYS_MMAN_H -# include -#else -# ifndef PROT_READ -# define PROT_READ 0x01 -# endif -# ifndef PROT_WRITE -# define PROT_WRITE 0x02 -# endif -# ifndef MAP_SHARED -# define MAP_SHARED 0x01 -# endif -# ifndef MAP_PRIVATE -# define MAP_PRIVATE 0x02 -# endif -#endif - -#ifndef MAP_FAILED -# define MAP_FAILED VOIDP(-1) -#endif - -#ifndef _SC_PAGESIZE -# ifdef _SC_PAGE_SIZE -# define _SC_PAGESIZE _SC_PAGE_SIZE -# endif -#endif - -#ifndef HAVE_STRCHR -extern char * strchr(char const * s, int c); -extern char * strrchr(char const * s, int c); -#endif - -/** - * INQUERY_CALL() tests whether the option handling function has been - * called by an inquery (help text needed, or option being reset), - * or called by a set-the-option operation. - */ -#define INQUERY_CALL(_o, _d) ( \ - ((_o) <= OPTPROC_EMIT_LIMIT) \ - || ((_d) == NULL) \ - || (((_d)->fOptState & OPTST_RESET) != 0) ) - -/** - * Define and initialize all the user visible strings. - * We do not do translations. If translations are to be done, then - * the client will provide a callback for that purpose. - */ -#undef DO_TRANSLATIONS -#include "autoopts/usage-txt.h" - -/** - * File pointer for usage output - */ -FILE * option_usage_fp; -/** - * If provided in the option structure - */ -static char const * program_pkgdatadir; -/** - * privately exported functions - */ -extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; - -#ifdef AUTOOPTS_INTERNAL - -#ifndef PKGDATADIR -# define PKGDATADIR "" -#endif -#define APOSTROPHE '\'' - -#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) -#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) -# include -#endif - -typedef struct { - size_t fnm_len; - uint32_t fnm_mask; - char const * fnm_name; -} ao_flag_names_t; - -/** - * Automated Options Usage Flags. - * NB: no entry may be a prefix of another entry - */ -#define AOFLAG_TABLE \ - _aof_(gnu, OPTPROC_GNUUSAGE ) \ - _aof_(autoopts, ~OPTPROC_GNUUSAGE) \ - _aof_(no_misuse_usage, OPTPROC_MISUSE ) \ - _aof_(misuse_usage, ~OPTPROC_MISUSE ) \ - _aof_(compute, OPTPROC_COMPUTE ) - -#define _aof_(_n, _f) AOUF_ ## _n ## _ID, -typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t; -#undef _aof_ - -#define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID), -typedef enum { AOFLAG_TABLE } ao_flags_t; -#undef _aof_ - -static char const zNil[] = ""; -static arg_types_t argTypes = { NULL }; -static char line_fmt_buf[32]; -static bool displayEnum = false; -static char const pkgdatadir_default[] = PKGDATADIR; -static char const * program_pkgdatadir = pkgdatadir_default; -static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; -static tePagerState pagerState = PAGER_STATE_INITIAL; - -static noreturn void option_exits(int exit_code); -static noreturn void fserr_exit(char const * prog, char const * op, - char const * fname); -static void fserr_warn(char const * prog, char const * op, - char const * fname); -static noreturn void ao_bug(char const * msg); - - FILE * option_usage_fp = NULL; - -static char const * pz_enum_err_fmt; - -tOptions * optionParseShellOptions = NULL; - -static char const * shell_prog = NULL; -static char * script_leader = NULL; -static char * script_trailer = NULL; -static char * script_text = NULL; -static bool print_exit = false; -#endif /* AUTOOPTS_INTERNAL */ - -#endif /* AUTOGEN_AUTOOPTS_H */ -/** - * @} - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/autoopts.h */ diff --git a/src/libopts/boolean.c b/src/libopts/boolean.c deleted file mode 100644 index 80e0b0e..0000000 --- a/src/libopts/boolean.c +++ /dev/null @@ -1,95 +0,0 @@ - -/** - * \file boolean.c - * - * Handle options with true/false values for arguments. - * - * @addtogroup autoopts - * @{ - */ -/* - * This routine will run run-on options through a pager so the - * user may examine, print or edit them at their leisure. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/*=export_func optionBooleanVal - * private: - * - * what: Decipher a boolean value - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Decipher a true or false value for a boolean valued option argument. - * The value is true, unless it starts with 'n' or 'f' or "#f" or - * it is an empty string or it is a number that evaluates to zero. -=*/ -void -optionBooleanVal(tOptions * opts, tOptDesc * od) -{ - char * pz; - bool res = true; - - if (INQUERY_CALL(opts, od)) - return; - - if (od->optArg.argString == NULL) { - od->optArg.argBool = false; - return; - } - - switch (*(od->optArg.argString)) { - case '0': - { - long val = strtol(od->optArg.argString, &pz, 0); - if ((val != 0) || (*pz != NUL)) - break; - } - /* FALLTHROUGH */ - case 'N': - case 'n': - case 'F': - case 'f': - case NUL: - res = false; - break; - case '#': - if (od->optArg.argString[1] != 'f') - break; - res = false; - } - - if (od->fOptState & OPTST_ALLOC_ARG) { - AGFREE(od->optArg.argString); - od->fOptState &= ~OPTST_ALLOC_ARG; - } - od->optArg.argBool = res; -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/boolean.c */ diff --git a/src/libopts/check.c b/src/libopts/check.c deleted file mode 100644 index 7e75e7e..0000000 --- a/src/libopts/check.c +++ /dev/null @@ -1,177 +0,0 @@ -/** - * @file check.c - * - * @brief option consistency checks. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * Check for conflicts based on "must" and "cannot" attributes. - */ -static bool -has_conflict(tOptions * pOpts, tOptDesc * od) -{ - if (od->pOptMust != NULL) { - int const * must = od->pOptMust; - - while (*must != NO_EQUIVALENT) { - tOptDesc * p = pOpts->pOptDesc + *(must++); - if (UNUSED_OPT(p)) { - const tOptDesc * ood = pOpts->pOptDesc + must[-1]; - fprintf(stderr, zneed_fmt, pOpts->pzProgName, - od->pz_Name, ood->pz_Name); - return true; - } - } - } - - if (od->pOptCant != NULL) { - int const * cant = od->pOptCant; - - while (*cant != NO_EQUIVALENT) { - tOptDesc * p = pOpts->pOptDesc + *(cant++); - if (SELECTED_OPT(p)) { - const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; - fprintf(stderr, zconflict_fmt, pOpts->pzProgName, - od->pz_Name, ood->pz_Name); - return true; - } - } - } - - return false; -} - -/** - * Check that the option occurs often enough. Too often is already checked. - */ -static bool -occurs_enough(tOptions * pOpts, tOptDesc * pOD) -{ - (void)pOpts; - - /* - * IF the occurrence counts have been satisfied, - * THEN there is no problem. - */ - if (pOD->optOccCt >= pOD->optMinCt) - return true; - - /* - * IF MUST_SET means SET and PRESET are okay, - * so min occurrence count doesn't count - */ - if ( (pOD->fOptState & OPTST_MUST_SET) - && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) - return true; - - if (pOD->optMinCt > 1) - fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, - pOD->optMinCt); - else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); - return false; -} - -/** - * Verify option consistency. - * - * Make sure that the argument list passes our consistency tests. - */ -static bool -is_consistent(tOptions * pOpts) -{ - tOptDesc * pOD = pOpts->pOptDesc; - int oCt = pOpts->presetOptCt; - - /* - * FOR each of "oCt" options, ... - */ - for (;;) { - /* - * IF the current option was provided on the command line - * THEN ensure that any "MUST" requirements are not - * "DEFAULT" (unspecified) *AND* ensure that any - * "CANT" options have not been SET or DEFINED. - */ - if (SELECTED_OPT(pOD)) { - if (has_conflict(pOpts, pOD)) - return false; - } - - /* - * IF this option is not equivalenced to another, - * OR it is equivalenced to itself (is the equiv. root) - * THEN we need to make sure it occurs often enough. - */ - if ( (pOD->optEquivIndex == NO_EQUIVALENT) - || (pOD->optEquivIndex == pOD->optIndex) ) - - if (! occurs_enough(pOpts, pOD)) - return false; - - if (--oCt <= 0) - break; - pOD++; - } - - /* - * IF we are stopping on errors, check to see if any remaining - * arguments are required to be there or prohibited from being there. - */ - if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { - - /* - * Check for prohibition - */ - if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { - if (pOpts->origArgCt > pOpts->curOptIdx) { - fprintf(stderr, zNoArgs, pOpts->pzProgName); - return false; - } - } - - /* - * ELSE not prohibited, check for being required - */ - else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { - if (pOpts->origArgCt <= pOpts->curOptIdx) { - fprintf(stderr, zargs_must, pOpts->pzProgName); - return false; - } - } - } - - return true; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/check.c */ diff --git a/src/libopts/compat/_Noreturn.h b/src/libopts/compat/_Noreturn.h deleted file mode 100644 index c44ad89..0000000 --- a/src/libopts/compat/_Noreturn.h +++ /dev/null @@ -1,10 +0,0 @@ -#if !defined _Noreturn && __STDC_VERSION__ < 201112 -# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ - || 0x5110 <= __SUNPRO_C) -# define _Noreturn __attribute__ ((__noreturn__)) -# elif 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn -# endif -#endif diff --git a/src/libopts/compat/compat.h b/src/libopts/compat/compat.h deleted file mode 100644 index 70a5652..0000000 --- a/src/libopts/compat/compat.h +++ /dev/null @@ -1,383 +0,0 @@ -/* -*- Mode: C -*- - * - * compat.h is free software. - * This file is part of AutoGen and AutoOpts. - * - * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * \file compat.h - * fake the preprocessor into handlng stuff portability - */ -#ifndef COMPAT_H_GUARD -#define COMPAT_H_GUARD 1 - -#if defined(HAVE_CONFIG_H) -# include - -#elif defined(_WIN32) && !defined(__CYGWIN__) -# include "windows-config.h" - -#else -# error "compat.h" requires "config.h" - choke me. -#endif - - -#ifndef HAVE_STRSIGNAL -# ifndef HAVE_RAW_DECL_STRSIGNAL - char * strsignal(int signo); -# endif -#endif - -#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ -#define __USE_GNU 1 /* exact same thing as above */ -#define __EXTENSIONS__ 1 /* and another way to call for it */ - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * SYSTEM HEADERS: - */ -#include -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#include -#if HAVE_SYS_PROCSET_H -# include -#endif -#include -#ifdef HAVE_SYS_WAIT_H -# include -#endif - -#if defined( HAVE_SOLARIS_SYSINFO ) -# include -#elif defined( HAVE_UNAME_SYSCALL ) -# include -#endif - -#ifdef DAEMON_ENABLED -# if HAVE_SYS_STROPTS_H -# include -# endif - -# if HAVE_SYS_SOCKET_H -# include -# endif - -# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H) -# error This system cannot support daemon processing - Choke Me. -# endif - -# if HAVE_SYS_POLL_H -# include -# endif - -# if HAVE_SYS_SELECT_H -# include -# endif - -# if HAVE_NETINET_IN_H -# include -# endif - -# if HAVE_SYS_UN_H -# include -# endif -#endif - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * USER HEADERS: - */ -#include -#include -#include - -/* - * Directory opening stuff: - */ -# if defined (_POSIX_SOURCE) -/* Posix does not require that the d_ino field be present, and some - systems do not provide it. */ -# define REAL_DIR_ENTRY(dp) 1 -# else /* !_POSIX_SOURCE */ -# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) -# endif /* !_POSIX_SOURCE */ - -# if defined (HAVE_DIRENT_H) -# include -# define D_NAMLEN(dirent) strlen((dirent)->d_name) -# else /* !HAVE_DIRENT_H */ -# define dirent direct -# define D_NAMLEN(dirent) (dirent)->d_namlen -# if defined (HAVE_SYS_NDIR_H) -# include -# endif /* HAVE_SYS_NDIR_H */ -# if defined (HAVE_SYS_DIR_H) -# include -# endif /* HAVE_SYS_DIR_H */ -# if defined (HAVE_NDIR_H) -# include -# endif /* HAVE_NDIR_H */ -# endif /* !HAVE_DIRENT_H */ - -#include -#ifdef HAVE_FCNTL_H -# include -#endif -#ifndef O_NONBLOCK -# define O_NONBLOCK FNDELAY -#endif - -#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H) -# include -#endif - -#if defined(HAVE_LIMITS_H) /* this is also in options.h */ -# include -#elif defined(HAVE_SYS_LIMITS_H) -# include -#endif /* HAVE_LIMITS/SYS_LIMITS_H */ - -#include -#include -#include - -#if defined(HAVE_STDINT_H) -# include - -#elif defined(HAVE_INTTYPES_H) -# include -#endif - -#include -#include -#include - -#ifdef HAVE_UTIME_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined(HAVE_STDBOOL_H) -# include -#elif ! defined(bool) - typedef enum { false = 0, true = 1 } _Bool; -# define bool _Bool - - /* The other macros must be usable in preprocessor directives. */ -# define false 0 -# define true 1 -#endif - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * FIXUPS and CONVIENCE STUFF: - */ -#ifdef __cplusplus -# define EXTERN extern "C" -#else -# define EXTERN extern -#endif - -/* some systems #def errno! and others do not declare it!! */ -#ifndef errno - extern int errno; -#endif - -/* Some machines forget this! */ - -# ifndef EXIT_FAILURE -# define EXIT_SUCCESS 0 -# define EXIT_FAILURE 1 -# endif - -#ifndef NUL -# define NUL '\0' -#endif - -#ifndef NULL -# define NULL 0 -#endif - -#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H) -# include -#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */ - -#if !defined (MAXPATHLEN) && defined (PATH_MAX) -# define MAXPATHLEN PATH_MAX -#endif /* !MAXPATHLEN && PATH_MAX */ - -#if !defined (MAXPATHLEN) && defined(_MAX_PATH) -# define PATH_MAX _MAX_PATH -# define MAXPATHLEN _MAX_PATH -#endif - -#if !defined (MAXPATHLEN) -# define MAXPATHLEN 4096 -#endif /* MAXPATHLEN */ - -#define AG_PATH_MAX ((size_t)MAXPATHLEN) - -#ifndef LONG_MAX -# define LONG_MAX ~(1L << (8*sizeof(long) -1)) -# define INT_MAX ~(1 << (8*sizeof(int) -1)) -#endif - -#ifndef ULONG_MAX -# define ULONG_MAX ~(OUL) -# define UINT_MAX ~(OU) -#endif - -#ifndef SHORT_MAX -# define SHORT_MAX ~(1 << (8*sizeof(short) - 1)) -#else -# define USHORT_MAX ~(OUS) -#endif - -#ifndef HAVE_INT8_T - typedef signed char int8_t; -# define HAVE_INT8_T 1 -#endif -#ifndef HAVE_UINT8_T - typedef unsigned char uint8_t; -# define HAVE_UINT8_T 1 -#endif -#ifndef HAVE_INT16_T - typedef signed short int16_t; -# define HAVE_INT16_T 1 -#endif -#ifndef HAVE_UINT16_T - typedef unsigned short uint16_t; -# define HAVE_UINT16_T 1 -#endif - -#ifndef HAVE_INT32_T -# if SIZEOF_INT == 4 - typedef signed int int32_t; -# elif SIZEOF_LONG == 4 - typedef signed long int32_t; -# endif -# define HAVE_INT32_T 1 -#endif - -#ifndef HAVE_UINT32_T -# if SIZEOF_INT == 4 - typedef unsigned int uint32_t; -# elif SIZEOF_LONG == 4 - typedef unsigned long uint32_t; -# else -# error Cannot create a uint32_t type. - Choke Me. -# endif -# define HAVE_UINT32_T 1 -#endif - -#ifndef HAVE_INTPTR_T -# if SIZEOF_CHARP == SIZEOF_LONG - typedef signed long intptr_t; -# else - typedef signed int intptr_t; -# endif -# define HAVE_INTPTR_T 1 -#endif - -#ifndef HAVE_UINTPTR_T -# if SIZEOF_CHARP == SIZEOF_LONG - typedef unsigned long intptr_t; -# else - typedef unsigned int intptr_t; -# endif -# define HAVE_INTPTR_T 1 -#endif - -#ifndef HAVE_UINT_T - typedef unsigned int uint_t; -# define HAVE_UINT_T 1 -#endif - -#ifndef HAVE_SIZE_T - typedef unsigned int size_t; -# define HAVE_SIZE_T 1 -#endif -#ifndef HAVE_WINT_T - typedef unsigned int wint_t; -# define HAVE_WINT_T 1 -#endif -#ifndef HAVE_PID_T - typedef signed int pid_t; -# define HAVE_PID_T 1 -#endif - -/* redefine these for BSD style string libraries */ -#ifndef HAVE_STRCHR -# define strchr index -# define strrchr rindex -#endif - -#ifdef USE_FOPEN_BINARY -# ifndef FOPEN_BINARY_FLAG -# define FOPEN_BINARY_FLAG "b" -# endif -# ifndef FOPEN_TEXT_FLAG -# define FOPEN_TEXT_FLAG "t" -# endif -#else -# ifndef FOPEN_BINARY_FLAG -# define FOPEN_BINARY_FLAG -# endif -# ifndef FOPEN_TEXT_FLAG -# define FOPEN_TEXT_FLAG -# endif -#endif - -#ifndef STR -# define _STR(s) #s -# define STR(s) _STR(s) -#endif - -/* ##### Pointer sized word ##### */ - -/* FIXME: the MAX stuff in here is broken! */ -#if SIZEOF_CHARP > SIZEOF_INT - typedef long t_word; - #define WORD_MAX LONG_MAX - #define WORD_MIN LONG_MIN -#else /* SIZEOF_CHARP <= SIZEOF_INT */ - typedef int t_word; - #define WORD_MAX INT_MAX - #define WORD_MIN INT_MIN -#endif - -#endif /* COMPAT_H_GUARD */ - -/* - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of compat/compat.h */ diff --git a/src/libopts/compat/pathfind.c b/src/libopts/compat/pathfind.c deleted file mode 100644 index e188b72..0000000 --- a/src/libopts/compat/pathfind.c +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- Mode: C -*- */ - -/* pathfind.c --- find a FILE MODE along PATH */ - -/* Author: Gary V Vaughan */ - -/* Code: */ - -static char * -pathfind( char const * path, - char const * fname, - char const * mode ); - -#include "compat.h" -#ifndef HAVE_PATHFIND -#if defined(__windows__) && !defined(__CYGWIN__) -static char * -pathfind( char const * path, - char const * fname, - char const * mode ) -{ - return strdup(fname); -} -#else - -static char * make_absolute(char const * string, char const * dot_path); -static char * canonicalize_pathname(char * path); -static char * extract_colon_unit(char * dir, char const * string, int * p_index); - -/** - * local implementation of pathfind. - * @param[in] path colon separated list of directories - * @param[in] fname the name we are hunting for - * @param[in] mode the required file mode - * @returns an allocated string with the full path, or NULL - */ -static char * -pathfind( char const * path, - char const * fname, - char const * mode ) -{ - int p_index = 0; - int mode_bits = 0; - char * res_path = NULL; - char zPath[ AG_PATH_MAX + 1 ]; - - if (strchr( mode, 'r' )) mode_bits |= R_OK; - if (strchr( mode, 'w' )) mode_bits |= W_OK; - if (strchr( mode, 'x' )) mode_bits |= X_OK; - - /* - * FOR each non-null entry in the colon-separated path, DO ... - */ - for (;;) { - DIR * dirP; - char * colon_unit = extract_colon_unit( zPath, path, &p_index ); - - if (colon_unit == NULL) - break; - - dirP = opendir( colon_unit ); - - /* - * IF the directory is inaccessable, THEN next directory - */ - if (dirP == NULL) - continue; - - for (;;) { - struct dirent *entP = readdir( dirP ); - - if (entP == (struct dirent *)NULL) - break; - - /* - * IF the file name matches the one we are looking for, ... - */ - if (strcmp(entP->d_name, fname) == 0) { - char * abs_name = make_absolute(fname, colon_unit); - - /* - * Make sure we can access it in the way we want - */ - if (access(abs_name, mode_bits) >= 0) { - /* - * We can, so normalize the name and return it below - */ - res_path = canonicalize_pathname(abs_name); - } - - free(abs_name); - break; - } - } - - closedir( dirP ); - - if (res_path != NULL) - break; - } - - return res_path; -} - -/* - * Turn STRING (a pathname) into an absolute pathname, assuming that - * DOT_PATH contains the symbolic location of `.'. This always returns - * a new string, even if STRING was an absolute pathname to begin with. - */ -static char * -make_absolute( char const * string, char const * dot_path ) -{ - char * result; - int result_len; - - if (!dot_path || *string == '/') { - result = strdup( string ); - } else { - if (dot_path && dot_path[0]) { - result = malloc( 2 + strlen( dot_path ) + strlen( string ) ); - strcpy( result, dot_path ); - result_len = (int)strlen(result); - if (result[result_len - 1] != '/') { - result[result_len++] = '/'; - result[result_len] = '\0'; - } - } else { - result = malloc( 3 + strlen( string ) ); - result[0] = '.'; result[1] = '/'; result[2] = '\0'; - result_len = 2; - } - - strcpy( result + result_len, string ); - } - - return result; -} - -/* - * Canonicalize PATH, and return a new path. The new path differs from - * PATH in that: - * - * Multiple `/'s are collapsed to a single `/'. - * Leading `./'s are removed. - * Trailing `/.'s are removed. - * Trailing `/'s are removed. - * Non-leading `../'s and trailing `..'s are handled by removing - * portions of the path. - */ -static char * -canonicalize_pathname( char *path ) -{ - int i, start; - char stub_char, *result; - - /* The result cannot be larger than the input PATH. */ - result = strdup( path ); - - stub_char = (*path == '/') ? '/' : '.'; - - /* Walk along RESULT looking for things to compact. */ - i = 0; - while (result[i]) { - while (result[i] != '\0' && result[i] != '/') - i++; - - start = i++; - - /* If we didn't find any slashes, then there is nothing left to - * do. - */ - if (!result[start]) - break; - - /* Handle multiple `/'s in a row. */ - while (result[i] == '/') - i++; - -#if !defined (apollo) - if ((start + 1) != i) -#else - if ((start + 1) != i && (start != 0 || i != 2)) -#endif /* apollo */ - { - strcpy( result + start + 1, result + i ); - i = start + 1; - } - - /* Handle backquoted `/'. */ - if (start > 0 && result[start - 1] == '\\') - continue; - - /* Check for trailing `/', and `.' by itself. */ - if ((start && !result[i]) - || (result[i] == '.' && !result[i+1])) { - result[--i] = '\0'; - break; - } - - /* Check for `../', `./' or trailing `.' by itself. */ - if (result[i] == '.') { - /* Handle `./'. */ - if (result[i + 1] == '/') { - strcpy( result + i, result + i + 1 ); - i = (start < 0) ? 0 : start; - continue; - } - - /* Handle `../' or trailing `..' by itself. */ - if (result[i + 1] == '.' && - (result[i + 2] == '/' || !result[i + 2])) { - while (--start > -1 && result[start] != '/') - ; - memmove( result + start + 1, result + i + 2, strlen(result + i + 2) + 1 ); - i = (start < 0) ? 0 : start; - continue; - } - } - } - - if (!*result) { - *result = stub_char; - result[1] = '\0'; - } - - return result; -} - -/* - * Given a string containing units of information separated by colons, - * return the next one pointed to by (P_INDEX), or NULL if there are no - * more. Advance (P_INDEX) to the character after the colon. - */ -static char * -extract_colon_unit(char * pzDir, char const * string, int * p_index) -{ - char * pzDest = pzDir; - int ix = *p_index; - - if (string == NULL) - return NULL; - - if ((unsigned)ix >= strlen( string )) - return NULL; - - { - char const * pzSrc = string + ix; - - while (*pzSrc == ':') pzSrc++; - - for (;;) { - char ch = (*(pzDest++) = *(pzSrc++)); - switch (ch) { - case ':': - pzDest[-1] = NUL; - /* FALLTHROUGH */ - case NUL: - goto copy_done; - } - - if ((unsigned long)(pzDest - pzDir) >= AG_PATH_MAX) - break; - } copy_done:; - - ix = (int)(pzSrc - string); - } - - if (*pzDir == NUL) - return NULL; - - *p_index = ix; - return pzDir; -} -#endif /* __windows__ / __CYGWIN__ */ -#endif /* HAVE_PATHFIND */ - -/* - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of compat/pathfind.c */ diff --git a/src/libopts/compat/snprintf.c b/src/libopts/compat/snprintf.c deleted file mode 100644 index eccea1f..0000000 --- a/src/libopts/compat/snprintf.c +++ /dev/null @@ -1,62 +0,0 @@ - -#ifndef HAVE_VPRINTF -#include "choke-me: no vprintf and no snprintf" - choke me. -#endif - -#if defined(HAVE_STDARG_H) -# include -# ifndef VA_START -# define VA_START(a, f) va_start(a, f) -# define VA_END(a) va_end(a) -# endif /* VA_START */ -# define SNV_USING_STDARG_H - -#elif defined(HAVE_VARARGS_H) -# include -# ifndef VA_START -# define VA_START(a, f) va_start(a) -# define VA_END(a) va_end(a) -# endif /* VA_START */ -# undef SNV_USING_STDARG_H - -#else -# include "must-have-stdarg-or-varargs" - choke me. -#endif - -static int -snprintf(char *str, size_t n, char const *fmt, ...) -{ - va_list ap; - int rval; - -#ifdef VSPRINTF_CHARSTAR - char *rp; - VA_START(ap, fmt); - rp = vsprintf(str, fmt, ap); - VA_END(ap); - rval = strlen(rp); - -#else - VA_START(ap, fmt); - rval = vsprintf(str, fmt, ap); - VA_END(ap); -#endif - - if (rval > n) { - fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n); - abort(); - } - return rval; -} - -static int -vsnprintf( char *str, size_t n, char const *fmt, va_list ap ) -{ -#ifdef VSPRINTF_CHARSTAR - return (strlen(vsprintf(str, fmt, ap))); -#else - return (vsprintf(str, fmt, ap)); -#endif -} diff --git a/src/libopts/compat/strchr.c b/src/libopts/compat/strchr.c deleted file mode 100644 index f409387..0000000 --- a/src/libopts/compat/strchr.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - SYNOPSIS - #include - - char *strchr(char const *s, int c); - - char *strrchr(char const *s, int c); - - DESCRIPTION - The strchr() function returns a pointer to the first occurrence of the - character c in the string s. - - The strrchr() function returns a pointer to the last occurrence of the - character c in the string s. - - Here "character" means "byte" - these functions do not work with wide - or multi-byte characters. - - RETURN VALUE - The strchr() and strrchr() functions return a pointer to the matched - character or NULL if the character is not found. - - CONFORMING TO - SVID 3, POSIX, BSD 4.3, ISO 9899 -*/ - -static char * -strchr(char const *s, int c); - -static char * -strrchr(char const *s, int c); - -static char * -strchr(char const *s, int c) -{ - do { - if ((unsigned char)*s == (unsigned char)c) - return s; - - } while (*(++s) != NUL); - - return NULL; -} - -static char * -strrchr(char const *s, int c) -{ - char const *e = s + strlen(s); - - for (;;) { - if (--e < s) - break; - - if ((unsigned char)*e == (unsigned char)c) - return e; - } - return NULL; -} - -/* - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of compat/strsignal.c */ diff --git a/src/libopts/compat/strdup.c b/src/libopts/compat/strdup.c deleted file mode 100644 index f3a4077..0000000 --- a/src/libopts/compat/strdup.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Platforms without strdup ?!?!?! - */ - -static char * -strdup( char const *s ); - -static char * -strdup( char const *s ) -{ - char *cp; - - if (s == NULL) - return NULL; - - cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup"); - - if (cp != NULL) - (void) strcpy(cp, s); - - return cp; -} diff --git a/src/libopts/compat/windows-config.h b/src/libopts/compat/windows-config.h deleted file mode 100644 index 7ce1636..0000000 --- a/src/libopts/compat/windows-config.h +++ /dev/null @@ -1,144 +0,0 @@ - -/** - * \file windows-config.h - * - * This file contains all of the routines that must be linked into - * an executable to use the generated option processing. The optional - * routines are in separately compiled modules so that they will not - * necessarily be linked in. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -#ifndef WINDOWS_CONFIG_HACKERY -#define WINDOWS_CONFIG_HACKERY 1 - -/* - * The definitions below have been stolen from NTP's config.h for Windows. - * However, they may be kept here in order to keep libopts independent from - * the NTP project. - */ -#ifndef __windows__ -# define __windows__ 4 -#endif - -/* - * Miscellaneous functions that Microsoft maps to other names - */ -#define snprintf _snprintf - -#define SIZEOF_INT 4 -#define SIZEOF_CHARP 4 -#define SIZEOF_LONG 4 -#define SIZEOF_SHORT 2 - -#define HAVE_LIMITS_H 1 -#define HAVE_STRDUP 1 -#define HAVE_STRCHR 1 -#define HAVE_FCNTL_H 1 - -/* - * VS.NET's version of wspiapi.h has a bug in it where it assigns a value - * to a variable inside an if statement. It should be comparing them. - * We prevent inclusion since we are not using this code so we don't have - * to see the warning messages - */ -#ifndef _WSPIAPI_H_ -#define _WSPIAPI_H_ -#endif - -/* Prevent inclusion of winsock.h in windows.h */ -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ -#endif - -#ifndef __RPCASYNC_H__ -#define __RPCASYNC_H__ -#endif - -/* Include Windows headers */ -#include -#include -#include - -/* - * Compatibility declarations for Windows, assuming SYS_WINNT - * has been defined. - */ -#define strdup _strdup -#define stat _stat /* struct stat from */ -#define unlink _unlink -#define fchmod( _x, _y ) -#define ssize_t SSIZE_T - -#include -#define open _open -#define close _close -#define read _read -#define write _write -#define lseek _lseek -#define pipe _pipe -#define dup2 _dup2 - -#define O_RDWR _O_RDWR -#define O_RDONLY _O_RDONLY -#define O_EXCL _O_EXCL - -#ifndef S_ISREG -# define S_IFREG _S_IFREG -# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) -#endif - -#ifndef S_ISDIR -# define S_IFDIR _S_IFDIR -# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) -#endif - -/* C99 exact size integer support. */ -#if defined(HAVE_INTTYPES_H) -# include - -#elif defined(HAVE_STDINT_H) -# include -# define MISSING_INTTYPES_H 1 - -#elif ! defined(ADDED_EXACT_SIZE_INTEGERS) -# define ADDED_EXACT_SIZE_INTEGERS 1 -# define MISSING_INTTYPES_H 1 - - typedef __int8 int8_t; - typedef unsigned __int8 uint8_t; - - typedef __int16 int16_t; - typedef unsigned __int16 uint16_t; - - typedef __int32 int32_t; - typedef unsigned __int32 uint32_t; - - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; - - typedef unsigned long uintptr_t; - typedef long intptr_t; -#endif - -#endif /* WINDOWS_CONFIG_HACKERY */ -/* windows-config.h ends here */ diff --git a/src/libopts/configfile.c b/src/libopts/configfile.c deleted file mode 100644 index 783a9d8..0000000 --- a/src/libopts/configfile.c +++ /dev/null @@ -1,1337 +0,0 @@ -/** - * \file configfile.c - * - * configuration/rc/ini file handling. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * Skip over some unknown attribute - * @param[in] txt start of skpped text - * @returns character after skipped text - */ -inline static char const * -skip_unkn(char const * txt) -{ - txt = BRK_END_XML_TOKEN_CHARS(txt); - return (*txt == NUL) ? NULL : txt; -} - -/*=export_func configFileLoad - * - * what: parse a configuration file - * arg: + char const * + fname + the file to load + - * - * ret_type: const tOptionValue * - * ret_desc: An allocated, compound value structure - * - * doc: - * This routine will load a named configuration file and parse the - * text as a hierarchically valued option. The option descriptor - * created from an option definition file is not used via this interface. - * The returned value is "named" with the input file name and is of - * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to - * @code{optionGetValue()}, @code{optionNextValue()} and - * @code{optionUnloadNested()}. - * - * err: - * If the file cannot be loaded or processed, @code{NULL} is returned and - * @var{errno} is set. It may be set by a call to either @code{open(2)} - * @code{mmap(2)} or other file system calls, or it may be: - * @itemize @bullet - * @item - * @code{ENOENT} - the file was not found. - * @item - * @code{ENOMSG} - the file was empty. - * @item - * @code{EINVAL} - the file contents are invalid -- not properly formed. - * @item - * @code{ENOMEM} - not enough memory to allocate the needed structures. - * @end itemize -=*/ -const tOptionValue * -configFileLoad(char const * fname) -{ - tmap_info_t cfgfile; - tOptionValue * res = NULL; - tOptionLoadMode save_mode = option_load_mode; - - char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile); - - if (TEXT_MMAP_FAILED_ADDR(txt)) - return NULL; /* errno is set */ - - option_load_mode = OPTION_LOAD_COOKED; - res = optionLoadNested(txt, fname, strlen(fname)); - - if (res == NULL) { - int err = errno; - text_munmap(&cfgfile); - errno = err; - } else - text_munmap(&cfgfile); - - option_load_mode = save_mode; - return res; -} - - -/*=export_func optionFindValue - * - * what: find a hierarcicaly valued option instance - * arg: + const tOptDesc * + odesc + an option with a nested arg type + - * arg: + char const * + name + name of value to find + - * arg: + char const * + val + the matching value + - * - * ret_type: const tOptionValue * - * ret_desc: a compound value structure - * - * doc: - * This routine will find an entry in a nested value option or configurable. - * It will search through the list and return a matching entry. - * - * err: - * The returned result is NULL and errno is set: - * @itemize @bullet - * @item - * @code{EINVAL} - the @code{pOptValue} does not point to a valid - * hierarchical option value. - * @item - * @code{ENOENT} - no entry matched the given name. - * @end itemize -=*/ -const tOptionValue * -optionFindValue(const tOptDesc * odesc, char const * name, char const * val) -{ - const tOptionValue * res = NULL; - - if ( (odesc == NULL) - || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { - errno = EINVAL; - } - - else if (odesc->optCookie == NULL) { - errno = ENOENT; - } - - else do { - tArgList * argl = odesc->optCookie; - int argct = argl->useCt; - void ** poptv = (void **)(argl->apzArgs); - - if (argct == 0) { - errno = ENOENT; - break; - } - - if (name == NULL) { - res = (tOptionValue *)*poptv; - break; - } - - while (--argct >= 0) { - const tOptionValue * ov = *(poptv++); - const tOptionValue * rv = optionGetValue(ov, name); - - if (rv == NULL) - continue; - - if (val == NULL) { - res = ov; - break; - } - } - if (res == NULL) - errno = ENOENT; - } while (false); - - return res; -} - - -/*=export_func optionFindNextValue - * - * FIXME: the handling of 'pzName' and 'pzVal' is just wrong. - * - * what: find a hierarcicaly valued option instance - * arg: + const tOptDesc * + odesc + an option with a nested arg type + - * arg: + const tOptionValue * + pPrevVal + the last entry + - * arg: + char const * + name + name of value to find + - * arg: + char const * + value + the matching value + - * - * ret_type: const tOptionValue * - * ret_desc: a compound value structure - * - * doc: - * This routine will find the next entry in a nested value option or - * configurable. It will search through the list and return the next entry - * that matches the criteria. - * - * err: - * The returned result is NULL and errno is set: - * @itemize @bullet - * @item - * @code{EINVAL} - the @code{pOptValue} does not point to a valid - * hierarchical option value. - * @item - * @code{ENOENT} - no entry matched the given name. - * @end itemize -=*/ -tOptionValue const * -optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal, - char const * pzName, char const * pzVal) -{ - bool old_found = false; - tOptionValue * res = NULL; - - (void)pzName; - (void)pzVal; - - if ( (odesc == NULL) - || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { - errno = EINVAL; - } - - else if (odesc->optCookie == NULL) { - errno = ENOENT; - } - - else do { - tArgList * argl = odesc->optCookie; - int ct = argl->useCt; - void ** poptv = (void **)argl->apzArgs; - - while (--ct >= 0) { - tOptionValue * pOV = *(poptv++); - if (old_found) { - res = pOV; - break; - } - if (pOV == pPrevVal) - old_found = true; - } - if (res == NULL) - errno = ENOENT; - } while (false); - - return res; -} - - -/*=export_func optionGetValue - * - * what: get a specific value from a hierarcical list - * arg: + const tOptionValue * + pOptValue + a hierarchcal value + - * arg: + char const * + valueName + name of value to get + - * - * ret_type: const tOptionValue * - * ret_desc: a compound value structure - * - * doc: - * This routine will find an entry in a nested value option or configurable. - * If "valueName" is NULL, then the first entry is returned. Otherwise, - * the first entry with a name that exactly matches the argument will be - * returned. If there is no matching value, NULL is returned and errno is - * set to ENOENT. If the provided option value is not a hierarchical value, - * NULL is also returned and errno is set to EINVAL. - * - * err: - * The returned result is NULL and errno is set: - * @itemize @bullet - * @item - * @code{EINVAL} - the @code{pOptValue} does not point to a valid - * hierarchical option value. - * @item - * @code{ENOENT} - no entry matched the given name. - * @end itemize -=*/ -tOptionValue const * -optionGetValue(tOptionValue const * oov, char const * vname) -{ - tArgList * arg_list; - tOptionValue * res = NULL; - - if ((oov == NULL) || (oov->valType != OPARG_TYPE_HIERARCHY)) { - errno = EINVAL; - return res; - } - arg_list = oov->v.nestVal; - - if (arg_list->useCt > 0) { - int ct = arg_list->useCt; - void ** ovlist = (void **)(arg_list->apzArgs); - - if (vname == NULL) { - res = (tOptionValue *)*ovlist; - - } else do { - tOptionValue * opt_val = *(ovlist++); - if (strcmp(opt_val->pzName, vname) == 0) { - res = opt_val; - break; - } - } while (--ct > 0); - } - if (res == NULL) - errno = ENOENT; - return res; -} - -/*=export_func optionNextValue - * - * what: get the next value from a hierarchical list - * arg: + const tOptionValue * + pOptValue + a hierarchcal list value + - * arg: + const tOptionValue * + pOldValue + a value from this list + - * - * ret_type: const tOptionValue * - * ret_desc: a compound value structure - * - * doc: - * This routine will return the next entry after the entry passed in. At the - * end of the list, NULL will be returned. If the entry is not found on the - * list, NULL will be returned and "@var{errno}" will be set to EINVAL. - * The "@var{pOldValue}" must have been gotten from a prior call to this - * routine or to "@code{opitonGetValue()}". - * - * err: - * The returned result is NULL and errno is set: - * @itemize @bullet - * @item - * @code{EINVAL} - the @code{pOptValue} does not point to a valid - * hierarchical option value or @code{pOldValue} does not point to a - * member of that option value. - * @item - * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. - * @end itemize -=*/ -tOptionValue const * -optionNextValue(tOptionValue const * ov_list,tOptionValue const * oov ) -{ - tArgList * arg_list; - tOptionValue * res = NULL; - int err = EINVAL; - - if ((ov_list == NULL) || (ov_list->valType != OPARG_TYPE_HIERARCHY)) { - errno = EINVAL; - return NULL; - } - arg_list = ov_list->v.nestVal; - { - int ct = arg_list->useCt; - void ** o_list = (void **)(arg_list->apzArgs); - - while (ct-- > 0) { - tOptionValue * nov = *(o_list++); - if (nov == oov) { - if (ct == 0) { - err = ENOENT; - - } else { - err = 0; - res = (tOptionValue *)*o_list; - } - break; - } - } - } - if (err != 0) - errno = err; - return res; -} - -/** - * Load a file containing presetting information (a configuration file). - */ -static void -file_preset(tOptions * opts, char const * fname, int dir) -{ - tmap_info_t cfgfile; - tOptState optst = OPTSTATE_INITIALIZER(PRESET); - opt_state_mask_t st_flags = optst.flags; - opt_state_mask_t fl_save = opts->fOptSet; - char * ftext = - text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile); - - if (TEXT_MMAP_FAILED_ADDR(ftext)) - return; - - /* - * While processing config files, we ignore errors. - */ - opts->fOptSet &= ~OPTPROC_ERRSTOP; - - if (dir == DIRECTION_CALLED) { - st_flags = OPTST_DEFINED; - dir = DIRECTION_PROCESS; - } - - /* - * IF this is called via "optionProcess", then we are presetting. - * This is the default and the PRESETTING bit will be set. - * If this is called via "optionFileLoad", then the bit is not set - * and we consider stuff set herein to be "set" by the client program. - */ - if ((opts->fOptSet & OPTPROC_PRESETTING) == 0) - st_flags = OPTST_SET; - - do { - optst.flags = st_flags; - ftext = SPN_WHITESPACE_CHARS(ftext); - - if (IS_VAR_FIRST_CHAR(*ftext)) { - ftext = handle_cfg(opts, &optst, ftext, dir); - - } else switch (*ftext) { - case '<': - if (IS_VAR_FIRST_CHAR(ftext[1])) - ftext = handle_struct(opts, &optst, ftext, dir); - - else switch (ftext[1]) { - case '?': - ftext = handle_directive(opts, ftext); - break; - - case '!': - ftext = handle_comment(ftext); - break; - - case '/': - ftext = strchr(ftext + 2, '>'); - if (ftext++ != NULL) - break; - /* FALLTHROUGH */ - - default: - ftext = NULL; - } - if (ftext == NULL) - goto all_done; - break; - - case '[': - ftext = handle_section(opts, ftext); - break; - - case '#': - ftext = strchr(ftext + 1, NL); - break; - - default: - goto all_done; /* invalid format */ - } - } while (ftext != NULL); - - all_done: - text_munmap(&cfgfile); - opts->fOptSet = fl_save; -} - -/** - * "txt" points to a "". - */ -static char * -handle_comment(char * txt) -{ - char * pz = strstr(txt, "-->"); - if (pz != NULL) - pz += 3; - return pz; -} - -/** - * "txt" points to the start of some value name. - * The end of the entry is the end of the line that is not preceded by - * a backslash escape character. The string value is always processed - * in "cooked" mode. - */ -static char * -handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir) -{ - char * pzName = txt++; - char * pzEnd = strchr(txt, NL); - - if (pzEnd == NULL) - return txt + strlen(txt); - - txt = SPN_VALUE_NAME_CHARS(txt); - txt = SPN_WHITESPACE_CHARS(txt); - if (txt > pzEnd) { - name_only: - *pzEnd++ = NUL; - load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); - return pzEnd; - } - - /* - * Either the first character after the name is a ':' or '=', - * or else we must have skipped over white space. Anything else - * is an invalid format and we give up parsing the text. - */ - if ((*txt == '=') || (*txt == ':')) { - txt = SPN_WHITESPACE_CHARS(txt+1); - if (txt > pzEnd) - goto name_only; - } else if (! IS_WHITESPACE_CHAR(txt[-1])) - return NULL; - - /* - * IF the value is continued, remove the backslash escape and push "pzEnd" - * on to a newline *not* preceded by a backslash. - */ - if (pzEnd[-1] == '\\') { - char * pcD = pzEnd-1; - char * pcS = pzEnd; - - for (;;) { - char ch = *(pcS++); - switch (ch) { - case NUL: - pcS = NULL; - /* FALLTHROUGH */ - - case NL: - *pcD = NUL; - pzEnd = pcS; - goto copy_done; - - case '\\': - if (*pcS == NL) - ch = *(pcS++); - /* FALLTHROUGH */ - default: - *(pcD++) = ch; - } - } copy_done:; - - } else { - /* - * The newline was not preceded by a backslash. NUL it out - */ - *(pzEnd++) = NUL; - } - - /* - * "pzName" points to what looks like text for one option/configurable. - * It is NUL terminated. Process it. - */ - load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); - - return pzEnd; -} - -/** - * "txt" points to a "'); - if (txt != NULL) - txt++; - return txt; -# undef DIRECTIVE_TABLE -} - -/** - * handle AutoOpts mode flags. - * - * @param[in,out] opts program option descriptor - * @param[in] txt scanning pointer - * @returns the next character to look at - */ -static char * -aoflags_directive(tOptions * opts, char * txt) -{ - char * pz; - - pz = SPN_WHITESPACE_CHARS(txt+1); - txt = strchr(pz, '>'); - if (txt != NULL) { - - size_t len = (unsigned)(txt - pz); - char * ftxt = AGALOC(len + 1, "aoflags"); - - memcpy(ftxt, pz, len); - ftxt[len] = NUL; - set_usage_flags(opts, ftxt); - AGFREE(ftxt); - - txt++; - } - - return txt; -} - -/** - * handle program segmentation of config file. - * - * @param[in,out] opts program option descriptor - * @param[in] txt scanning pointer - * @returns the next character to look at - */ -static char * -program_directive(tOptions * opts, char * txt) -{ - size_t name_len = strlen(opts->pzProgName); - - for (;; txt += zCfgProg_LEN) { - txt = SPN_WHITESPACE_CHARS(txt); - - if ( (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0) - && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) - - return txt + name_len; - - txt = strstr(txt, zCfgProg); - if (txt == NULL) - return txt; - } - - for (;;) { - if (*txt == NUL) - return NULL; - - if (*(txt++) == '>') - return txt; - } -} - -/** - * "txt" points to a '[' character. - * The "traditional" [PROG_NAME] segmentation of the config file. - * Do not ever mix with the "" variation. - * The templates reject program names over 16 characters. - * - * @param[in,out] opts program option descriptor - * @param[in] txt scanning pointer - * @returns the next character to look at - */ -static char * -handle_section(tOptions * opts, char * txt) -{ - size_t len = strlen(opts->pzPROGNAME); - if ( (strncmp(txt+1, opts->pzPROGNAME, len) == 0) - && (txt[len+1] == ']')) - return strchr(txt + len + 2, NL); - - if (len > 16) - return NULL; - - { - char z[24] = "["; - memcpy(z+1, opts->pzPROGNAME, len); - z[++len] = ']'; - z[++len] = NUL; - txt = strstr(txt, z); - } - - if (txt != NULL) - txt = strchr(txt, NL); - return txt; -} - -/** - * parse XML encodings - */ -static int -parse_xml_encoding(char ** ppz) -{ -# define XMLTABLE \ - _xmlNm_(amp, '&') \ - _xmlNm_(lt, '<') \ - _xmlNm_(gt, '>') \ - _xmlNm_(ff, '\f') \ - _xmlNm_(ht, '\t') \ - _xmlNm_(cr, '\r') \ - _xmlNm_(vt, '\v') \ - _xmlNm_(bel, '\a') \ - _xmlNm_(nl, NL) \ - _xmlNm_(space, ' ') \ - _xmlNm_(quot, '"') \ - _xmlNm_(apos, '\'') - - static struct { - char const * const nm_str; - unsigned short nm_len; - short nm_val; - } const xml_names[] = { -# define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v }, - XMLTABLE -# undef _xmlNm_ -# undef XMLTABLE - }; - - static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]); - int base = 10; - - char * pz = *ppz; - - if (*pz == '#') { - pz++; - goto parse_number; - } - - if (IS_DEC_DIGIT_CHAR(*pz)) { - unsigned long v; - - parse_number: - switch (*pz) { - case 'x': case 'X': - /* - * Some forms specify hex with: &#xNN; - */ - base = 16; - pz++; - break; - - case '0': - /* - *  is hex and  is decimal. Cool. - * Ya gotta love it. - */ - if (pz[1] == '0') - base = 16; - break; - } - - v = strtoul(pz, &pz, base); - if ((*pz != ';') || (v > 0x7F)) - return NUL; - *ppz = pz + 1; - return (int)v; - } - - { - int ix = 0; - do { - if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len) - == 0) { - *ppz = pz + xml_names[ix].nm_len; - return xml_names[ix].nm_val; - } - } while (++ix < nm_ct); - } - - return NUL; -} - -/** - * Find the end marker for the named section of XML. - * Trim that text there, trimming trailing white space for all modes - * except for OPTION_LOAD_UNCOOKED. - */ -static char * -trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode) -{ - size_t nm_len = strlen(pznm); - char * etext; - - { - char z[64], *pz = z; - - if (nm_len + 4 >= sizeof(z)) - pz = AGALOC(nm_len + 4, "scan name"); - - pz[0] = '<'; - pz[1] = '/'; - memcpy(pz+2, pznm, nm_len); - nm_len += 2; - pz[nm_len++] = '>'; - pz[nm_len] = NUL; - - *intxt = ' '; - etext = strstr(intxt, pz); - if (pz != z) AGFREE(pz); - } - - if (etext == NULL) - return etext; - - { - char * result = etext + nm_len; - - if (mode != OPTION_LOAD_UNCOOKED) - etext = SPN_WHITESPACE_BACK(intxt, etext); - - *etext = NUL; - return result; - } -} - -/** - */ -static void -cook_xml_text(char * pzData) -{ - char * pzs = pzData; - char * pzd = pzData; - char bf[4]; - bf[2] = NUL; - - for (;;) { - int ch = ((int)*(pzs++)) & 0xFF; - switch (ch) { - case NUL: - *pzd = NUL; - return; - - case '&': - ch = parse_xml_encoding(&pzs); - *(pzd++) = (char)ch; - if (ch == NUL) - return; - break; - - case '%': - bf[0] = *(pzs++); - bf[1] = *(pzs++); - if ((bf[0] == NUL) || (bf[1] == NUL)) { - *pzd = NUL; - return; - } - - ch = (int)strtoul(bf, NULL, 16); - /* FALLTHROUGH */ - - default: - *(pzd++) = (char)ch; - } - } -} - -/** - * "txt" points to a '<' character, followed by an alpha. - * The end of the entry is either the "/>" following the name, or else a - * "" string. - */ -static char * -handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir) -{ - tOptionLoadMode mode = option_load_mode; - tOptionValue valu; - - char * pzName = ++txt; - char * pzData; - char * pcNulPoint; - - txt = SPN_VALUE_NAME_CHARS(txt); - pcNulPoint = txt; - valu.valType = OPARG_TYPE_STRING; - - switch (*txt) { - case ' ': - case '\t': - txt = VOIDP(parse_attrs( - opts, SPN_WHITESPACE_CHARS(txt), &mode, &valu)); - if (txt == NULL) - return txt; - if (*txt == '>') - break; - if (*txt != '/') - return NULL; - /* FALLTHROUGH */ - - case '/': - if (txt[1] != '>') - return NULL; - *txt = NUL; - txt += 2; - load_opt_line(opts, ost, pzName, dir, mode); - return txt; - - case '>': - break; - - default: - txt = strchr(txt, '>'); - if (txt != NULL) - txt++; - return txt; - } - - /* - * If we are here, we have a value. "txt" points to a closing angle - * bracket. Separate the name from the value for a moment. - */ - *pcNulPoint = NUL; - pzData = ++txt; - txt = trim_xml_text(txt, pzName, mode); - if (txt == NULL) - return txt; - - /* - * Rejoin the name and value for parsing by "load_opt_line()". - * Erase any attributes parsed by "parse_attrs()". - */ - memset(pcNulPoint, ' ', (size_t)(pzData - pcNulPoint)); - - /* - * If we are getting a "string" value that is to be cooked, - * then process the XML-ish &xx; XML-ish and %XX hex characters. - */ - if ( (valu.valType == OPARG_TYPE_STRING) - && (mode == OPTION_LOAD_COOKED)) - cook_xml_text(pzData); - - /* - * "pzName" points to what looks like text for one option/configurable. - * It is NUL terminated. Process it. - */ - load_opt_line(opts, ost, pzName, dir, mode); - - return txt; -} - -/** - * Load a configuration file. This may be invoked either from - * scanning the "homerc" list, or from a specific file request. - * (see "optionFileLoad()", the implementation for --load-opts) - */ -static void -intern_file_load(tOptions * opts) -{ - uint32_t svfl; - int idx; - int inc; - char f_name[ AG_PATH_MAX+1 ]; - - if (opts->papzHomeList == NULL) - return; - - svfl = opts->fOptSet; - inc = DIRECTION_PRESET; - - /* - * Never stop on errors in config files. - */ - opts->fOptSet &= ~OPTPROC_ERRSTOP; - - /* - * Find the last RC entry (highest priority entry) - */ - for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ; - - /* - * For every path in the home list, ... *TWICE* We start at the last - * (highest priority) entry, work our way down to the lowest priority, - * handling the immediate options. - * Then we go back up, doing the normal options. - */ - for (;;) { - struct stat sb; - cch_t * path; - - /* - * IF we've reached the bottom end, change direction - */ - if (idx < 0) { - inc = DIRECTION_PROCESS; - idx = 0; - } - - path = opts->papzHomeList[ idx ]; - - /* - * IF we've reached the top end, bail out - */ - if (path == NULL) - break; - - idx += inc; - - if (! optionMakePath(f_name, (int)sizeof(f_name), - path, opts->pzProgPath)) - continue; - - /* - * IF the file name we constructed is a directory, - * THEN append the Resource Configuration file name - * ELSE we must have the complete file name - */ - if (stat(f_name, &sb) != 0) - continue; /* bogus name - skip the home list entry */ - - if (S_ISDIR(sb.st_mode)) { - size_t len = strlen(f_name); - size_t nln = strlen(opts->pzRcName) + 1; - char * pz = f_name + len; - - if (len + 1 + nln >= sizeof(f_name)) - continue; - - if (pz[-1] != DIRCH) - *(pz++) = DIRCH; - memcpy(pz, opts->pzRcName, nln); - } - - file_preset(opts, f_name, inc); - - /* - * IF we are now to skip config files AND we are presetting, - * THEN change direction. We must go the other way. - */ - { - tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; - if (DISABLED_OPT(od) && PRESETTING(inc)) { - idx -= inc; /* go back and reprocess current file */ - inc = DIRECTION_PROCESS; - } - } - } /* twice for every path in the home list, ... */ - - opts->fOptSet = svfl; -} - -/*=export_func optionFileLoad - * - * what: Load the locatable config files, in order - * - * arg: + tOptions * + opts + program options descriptor + - * arg: + char const * + prog + program name + - * - * ret_type: int - * ret_desc: 0 -> SUCCESS, -1 -> FAILURE - * - * doc: - * - * This function looks in all the specified directories for a configuration - * file ("rc" file or "ini" file) and processes any found twice. The first - * time through, they are processed in reverse order (last file first). At - * that time, only "immediate action" configurables are processed. For - * example, if the last named file specifies not processing any more - * configuration files, then no more configuration files will be processed. - * Such an option in the @strong{first} named directory will have no effect. - * - * Once the immediate action configurables have been handled, then the - * directories are handled in normal, forward order. In that way, later - * config files can override the settings of earlier config files. - * - * See the AutoOpts documentation for a thorough discussion of the - * config file format. - * - * Configuration files not found or not decipherable are simply ignored. - * - * err: Returns the value, "-1" if the program options descriptor - * is out of date or indecipherable. Otherwise, the value "0" will - * always be returned. -=*/ -int -optionFileLoad(tOptions * opts, char const * prog) -{ - if (! SUCCESSFUL(validate_struct(opts, prog))) - return -1; - - /* - * The pointer to the program name is "const". However, the - * structure is in writable memory, so we coerce the address - * of this pointer to point to writable memory. - */ - { - char const ** pp = VOIDP(&(opts->pzProgName)); - *pp = prog; - } - - intern_file_load(opts); - return 0; -} - -/*=export_func optionLoadOpt - * private: - * - * what: Load an option rc/ini file - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + odesc + the descriptor for this arg + - * - * doc: - * Processes the options found in the file named with - * odesc->optArg.argString. -=*/ -void -optionLoadOpt(tOptions * opts, tOptDesc * odesc) -{ - struct stat sb; - - if (opts <= OPTPROC_EMIT_LIMIT) - return; - - /* - * IF the option is not being disabled, THEN load the file. There must - * be a file. (If it is being disabled, then the disablement processing - * already took place. It must be done to suppress preloading of ini/rc - * files.) - */ - if ( DISABLED_OPT(odesc) - || ((odesc->fOptState & OPTST_RESET) != 0)) - return; - - if (stat(odesc->optArg.argString, &sb) != 0) { - if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) - return; - - fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); - /* NOT REACHED */ - } - - if (! S_ISREG(sb.st_mode)) { - if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) - return; - errno = EINVAL; - fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); - /* NOT REACHED */ - } - - file_preset(opts, odesc->optArg.argString, DIRECTION_CALLED); -} - -/** - * Parse the various attributes of an XML-styled config file entry - * - * @returns NULL on failure, otherwise the scan point - */ -static char const * -parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, - tOptionValue * pType) -{ - size_t len = 0; - - for (;;) { - len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt); - - /* - * The enumeration used in this switch is derived from this switch - * statement itself. The "find_option_xat_attribute_cmd" function - * will return XAT_CMD_MEMBERS for the "txt" string value - * "members", etc. - */ - switch (find_option_xat_attribute_cmd(txt, len)) { - case XAT_CMD_TYPE: - txt = parse_value(txt+len, pType); - break; - - case XAT_CMD_WORDS: - txt = parse_keyword(opts, txt+len, pType); - break; - - case XAT_CMD_MEMBERS: - txt = parse_set_mem(opts, txt+len, pType); - break; - - case XAT_CMD_COOKED: - txt += len; - if (! IS_END_XML_TOKEN_CHAR(*txt)) - goto invalid_kwd; - - *pMode = OPTION_LOAD_COOKED; - break; - - case XAT_CMD_UNCOOKED: - txt += len; - if (! IS_END_XML_TOKEN_CHAR(*txt)) - goto invalid_kwd; - - *pMode = OPTION_LOAD_UNCOOKED; - break; - - case XAT_CMD_KEEP: - txt += len; - if (! IS_END_XML_TOKEN_CHAR(*txt)) - goto invalid_kwd; - - *pMode = OPTION_LOAD_KEEP; - break; - - default: - case XAT_INVALID_CMD: - invalid_kwd: - pType->valType = OPARG_TYPE_NONE; - return skip_unkn(txt); - } - - if (txt == NULL) - return NULL; - txt = SPN_WHITESPACE_CHARS(txt); - switch (*txt) { - case '/': pType->valType = OPARG_TYPE_NONE; - /* FALLTHROUGH */ - case '>': return txt; - } - if (! IS_LOWER_CASE_CHAR(*txt)) - return NULL; - } -} - -/** - * "txt" points to the character after "words=". - * What should follow is a name of a keyword (enumeration) list. - * - * @param opts unused - * @param[in] txt keyword to skip over - * @param type unused value type - * @returns pointer after skipped text - */ -static char const * -parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ) -{ - (void)opts; - (void)typ; - - return skip_unkn(txt); -} - -/** - * "txt" points to the character after "members=" - * What should follow is a name of a "set membership". - * A collection of bit flags. - * - * @param opts unused - * @param[in] txt keyword to skip over - * @param type unused value type - * @returns pointer after skipped text - */ -static char const * -parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ) -{ - (void)opts; - (void)typ; - - return skip_unkn(txt); -} - -/** - * parse the type. The keyword "type" was found, now figure out - * the type that follows the type. - * - * @param[in] txt points to the '=' character after the "type" keyword. - * @param[out] typ where to store the type found - * @returns the next byte after the type name - */ -static char const * -parse_value(char const * txt, tOptionValue * typ) -{ - size_t len = 0; - - if (*(txt++) != '=') - goto woops; - - len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt); - - if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) { - woops: - typ->valType = OPARG_TYPE_NONE; - return skip_unkn(txt + len); - } - - /* - * The enumeration used in this switch is derived from this switch - * statement itself. The "find_option_value_type_cmd" function - * will return VTP_CMD_INTEGER for the "txt" string value - * "integer", etc. - */ - switch (find_option_value_type_cmd(txt, len)) { - default: - case VTP_INVALID_CMD: goto woops; - - case VTP_CMD_STRING: - typ->valType = OPARG_TYPE_STRING; - break; - - case VTP_CMD_INTEGER: - typ->valType = OPARG_TYPE_NUMERIC; - break; - - case VTP_CMD_BOOL: - case VTP_CMD_BOOLEAN: - typ->valType = OPARG_TYPE_BOOLEAN; - break; - - case VTP_CMD_KEYWORD: - typ->valType = OPARG_TYPE_ENUMERATION; - break; - - case VTP_CMD_SET: - case VTP_CMD_SET_MEMBERSHIP: - typ->valType = OPARG_TYPE_MEMBERSHIP; - break; - - case VTP_CMD_NESTED: - case VTP_CMD_HIERARCHY: - typ->valType = OPARG_TYPE_HIERARCHY; - } - - return txt + len; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/configfile.c */ diff --git a/src/libopts/cook.c b/src/libopts/cook.c deleted file mode 100644 index 5240540..0000000 --- a/src/libopts/cook.c +++ /dev/null @@ -1,320 +0,0 @@ -/** - * \file cook.c - * - * This file contains the routines that deal with processing quoted strings - * into an internal format. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/*=export_func ao_string_cook_escape_char - * private: - * - * what: escape-process a string fragment - * arg: + char const * + pzScan + points to character after the escape + - * arg: + char * + pRes + Where to put the result byte + - * arg: + unsigned int + nl_ch + replacement char if scanned char is \n + - * - * ret-type: unsigned int - * ret-desc: The number of bytes consumed processing the escaped character. - * - * doc: - * - * This function converts "t" into "\t" and all your other favorite - * escapes, including numeric ones: hex and ocatal, too. - * The returned result tells the caller how far to advance the - * scan pointer (passed in). The default is to just pass through the - * escaped character and advance the scan by one. - * - * Some applications need to keep an escaped newline, others need to - * suppress it. This is accomplished by supplying a '\n' replacement - * character that is different from \n, if need be. For example, use - * 0x7F and never emit a 0x7F. - * - * err: @code{NULL} is returned if the string is mal-formed. -=*/ -unsigned int -ao_string_cook_escape_char(char const * pzIn, char * pRes, uint_t nl) -{ - unsigned int res = 1; - - switch (*pRes = *pzIn++) { - case NUL: /* NUL - end of input string */ - return 0; - case '\r': - if (*pzIn != NL) - return 1; - res++; - /* FALLTHROUGH */ - case NL: /* NL - emit newline */ - *pRes = (char)nl; - return res; - - case 'a': *pRes = '\a'; break; - case 'b': *pRes = '\b'; break; - case 'f': *pRes = '\f'; break; - case 'n': *pRes = NL; break; - case 'r': *pRes = '\r'; break; - case 't': *pRes = '\t'; break; - case 'v': *pRes = '\v'; break; - - case 'x': - case 'X': /* HEX Escape */ - if (IS_HEX_DIGIT_CHAR(*pzIn)) { - char z[4]; - unsigned int ct = 0; - - do { - z[ct] = pzIn[ct]; - if (++ct >= 2) - break; - } while (IS_HEX_DIGIT_CHAR(pzIn[ct])); - z[ct] = NUL; - *pRes = (char)strtoul(z, NULL, 16); - return ct + 1; - } - break; - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - { - /* - * IF the character copied was an octal digit, - * THEN set the output character to an octal value. - * The 3 octal digit result might exceed 0xFF, so check it. - */ - char z[4]; - unsigned long val; - unsigned int ct = 0; - - z[ct++] = *--pzIn; - while (IS_OCT_DIGIT_CHAR(pzIn[ct])) { - z[ct] = pzIn[ct]; - if (++ct >= 3) - break; - } - - z[ct] = NUL; - val = strtoul(z, NULL, 8); - if (val > 0xFF) - val = 0xFF; - *pRes = (char)val; - return ct; - } - - default: /* quoted character is result character */; - } - - return res; -} - -/** - * count newlines between start and end - */ -static char * -nl_count(char * start, char * end, int * lnct_p) -{ - while (start < end) { - if (*(start++) == NL) - (*lnct_p)++; - } - return end; -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * A quoted string has been found. - * Find the end of it and compress any escape sequences. - */ -static bool -contiguous_quote(char ** pps, char * pq, int * lnct_p) -{ - char * ps = *pps + 1; - - for (;;) { - while (IS_WHITESPACE_CHAR(*ps)) - if (*(ps++) == NL) - (*lnct_p)++; - - /* - * IF the next character is a quote character, - * THEN we will concatenate the strings. - */ - switch (*ps) { - case '"': - case '\'': - *pq = *(ps++); /* assign new quote character and return */ - *pps = ps; - return true; - - case '/': - /* - * Allow for a comment embedded in the concatenated string. - */ - switch (ps[1]) { - default: - goto fail_return; - - case '/': - /* - * Skip to end of line - */ - ps = strchr(ps, NL); - if (ps == NULL) - goto fail_return; - break; - - case '*': - ps = nl_count(ps + 2, strstr(ps + 2, "*/"), lnct_p); - if (ps == NULL) - goto fail_return; - ps += 2; - } - continue; - - default: - /* - * The next non-whitespace character is not a quote. - * The series of quoted strings has come to an end. - */ - *pps = ps; - return false; - } - } - - fail_return: - *pps = NULL; - return false; -} - -/*=export_func ao_string_cook - * private: - * - * what: concatenate and escape-process strings - * arg: + char * + pzScan + The *MODIFIABLE* input buffer + - * arg: + int * + lnct_p + The (possibly NULL) pointer to a line count + - * - * ret-type: char * - * ret-desc: The address of the text following the processed strings. - * The return value is NULL if the strings are ill-formed. - * - * doc: - * - * A series of one or more quoted strings are concatenated together. - * If they are quoted with double quotes (@code{"}), then backslash - * escapes are processed per the C programming language. If they are - * single quote strings, then the backslashes are honored only when they - * precede another backslash or a single quote character. - * - * err: @code{NULL} is returned if the string(s) is/are mal-formed. -=*/ -char * -ao_string_cook(char * pzScan, int * lnct_p) -{ - int l = 0; - char q = *pzScan; - - /* - * It is a quoted string. Process the escape sequence characters - * (in the set "abfnrtv") and make sure we find a closing quote. - */ - char * pzD = pzScan++; - char * pzS = pzScan; - - if (lnct_p == NULL) - lnct_p = &l; - - for (;;) { - /* - * IF the next character is the quote character, THEN we may end the - * string. We end it unless the next non-blank character *after* the - * string happens to also be a quote. If it is, then we will change - * our quote character to the new quote character and continue - * condensing text. - */ - while (*pzS == q) { - *pzD = NUL; /* This is probably the end of the line */ - if (! contiguous_quote(&pzS, &q, lnct_p)) - return pzS; - } - - /* - * We are inside a quoted string. Copy text. - */ - switch (*(pzD++) = *(pzS++)) { - case NUL: - return NULL; - - case NL: - (*lnct_p)++; - break; - - case '\\': - /* - * IF we are escaping a new line, - * THEN drop both the escape and the newline from - * the result string. - */ - if (*pzS == NL) { - pzS++; - pzD--; - (*lnct_p)++; - } - - /* - * ELSE IF the quote character is '"' or '`', - * THEN we do the full escape character processing - */ - else if (q != '\'') { - unsigned int ct; - ct = ao_string_cook_escape_char(pzS, pzD-1, (uint_t)NL); - if (ct == 0) - return NULL; - - pzS += ct; - } /* if (q != '\'') */ - - /* - * OTHERWISE, we only process "\\", "\'" and "\#" sequences. - * The latter only to easily hide preprocessing directives. - */ - else switch (*pzS) { - case '\\': - case '\'': - case '#': - pzD[-1] = *pzS++; - } - } /* switch (*(pzD++) = *(pzS++)) */ - } /* for (;;) */ -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/cook.c */ diff --git a/src/libopts/enum.c b/src/libopts/enum.c deleted file mode 100644 index 7f92e0b..0000000 --- a/src/libopts/enum.c +++ /dev/null @@ -1,628 +0,0 @@ - -/** - * \file enumeration.c - * - * Handle options with enumeration names and bit mask bit names - * for their arguments. - * - * @addtogroup autoopts - * @{ - */ -/* - * This routine will run run-on options through a pager so the - * user may examine, print or edit them at their leisure. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -static void -enum_err(tOptions * pOpts, tOptDesc * pOD, - char const * const * paz_names, int name_ct) -{ - size_t max_len = 0; - size_t ttl_len = 0; - int ct_down = name_ct; - int hidden = 0; - - /* - * A real "pOpts" pointer means someone messed up. Give a real error. - */ - if (pOpts > OPTPROC_EMIT_LIMIT) - fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName, - pOD->optArg.argString, pOD->pz_Name); - - fprintf(option_usage_fp, zValidKeys, pOD->pz_Name); - - /* - * If the first name starts with this funny character, then we have - * a first value with an unspellable name. You cannot specify it. - * So, we don't list it either. - */ - if (**paz_names == 0x7F) { - paz_names++; - hidden = 1; - ct_down = --name_ct; - } - - /* - * Figure out the maximum length of any name, plus the total length - * of all the names. - */ - { - char const * const * paz = paz_names; - - do { - size_t len = strlen(*(paz++)) + 1; - if (len > max_len) - max_len = len; - ttl_len += len; - } while (--ct_down > 0); - - ct_down = name_ct; - } - - /* - * IF any one entry is about 1/2 line or longer, print one per line - */ - if (max_len > 35) { - do { - fprintf(option_usage_fp, ENUM_ERR_LINE, *(paz_names++)); - } while (--ct_down > 0); - } - - /* - * ELSE IF they all fit on one line, then do so. - */ - else if (ttl_len < 76) { - fputc(' ', option_usage_fp); - do { - fputc(' ', option_usage_fp); - fputs(*(paz_names++), option_usage_fp); - } while (--ct_down > 0); - fputc(NL, option_usage_fp); - } - - /* - * Otherwise, columnize the output - */ - else { - unsigned int ent_no = 0; - char fmt[16]; /* format for all-but-last entries on a line */ - - if (snprintf(fmt, 16, ENUM_ERR_WIDTH, (int)max_len) >= 16) - option_exits(EXIT_FAILURE); - max_len = 78 / max_len; /* max_len is now max entries on a line */ - fputs(TWO_SPACES_STR, option_usage_fp); - - /* - * Loop through all but the last entry - */ - ct_down = name_ct; - while (--ct_down > 0) { - if (++ent_no == max_len) { - /* - * Last entry on a line. Start next line, too. - */ - fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++)); - ent_no = 0; - } - - else - fprintf(option_usage_fp, fmt, *(paz_names++) ); - } - fprintf(option_usage_fp, NLSTR_FMT, *paz_names); - } - - if (pOpts > OPTPROC_EMIT_LIMIT) { - fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); - - (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - } - - if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { - fprintf(option_usage_fp, zLowerBits, name_ct); - fputs(zSetMemberSettings, option_usage_fp); - } else { - fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); - } -} - -/** - * Convert a name or number into a binary number. - * "~0" and "-1" will be converted to the largest value in the enumeration. - * - * @param name the keyword name (number) to convert - * @param pOpts the program's option descriptor - * @param pOD the option descriptor for this option - * @param paz_names the list of keywords for this option - * @param name_ct the count of keywords - */ -static uintptr_t -find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, - char const * const * paz_names, unsigned int name_ct) -{ - /* - * Return the matching index as a pointer sized integer. - * The result gets stashed in a char * pointer. - */ - uintptr_t res = name_ct; - size_t len = strlen((char *)name); - uintptr_t idx; - - if (IS_DEC_DIGIT_CHAR(*name)) { - char * pz = VOIDP(name); - unsigned long val = strtoul(pz, &pz, 0); - if ((*pz == NUL) && (val < name_ct)) - return (uintptr_t)val; - pz_enum_err_fmt = znum_too_large; - option_usage_fp = stderr; - enum_err(pOpts, pOD, paz_names, (int)name_ct); - return name_ct; - } - - if (IS_INVERSION_CHAR(*name) && (name[2] == NUL)) { - if ( ((name[0] == '~') && (name[1] == '0')) - || ((name[0] == '-') && (name[1] == '1'))) - return (uintptr_t)(name_ct - 1); - goto oops; - } - - /* - * Look for an exact match, but remember any partial matches. - * Multiple partial matches means we have an ambiguous match. - */ - for (idx = 0; idx < name_ct; idx++) { - if (strncmp((char *)paz_names[idx], (char *)name, len) == 0) { - if (paz_names[idx][len] == NUL) - return idx; /* full match */ - - if (res == name_ct) - res = idx; /* save partial match */ - else - res = (uintptr_t)~0; /* may yet find full match */ - } - } - - if (res < name_ct) - return res; /* partial match */ - - oops: - - pz_enum_err_fmt = (res == name_ct) ? zNoKey : zambiguous_key; - option_usage_fp = stderr; - enum_err(pOpts, pOD, paz_names, (int)name_ct); - return name_ct; -} - - -/*=export_func optionKeywordName - * what: Convert between enumeration values and strings - * private: - * - * arg: tOptDesc *, pOD, enumeration option description - * arg: unsigned int, enum_val, the enumeration value to map - * - * ret_type: char const * - * ret_desc: the enumeration name from const memory - * - * doc: This converts an enumeration value into the matching string. -=*/ -char const * -optionKeywordName(tOptDesc * pOD, unsigned int enum_val) -{ - tOptDesc od = { 0 }; - od.optArg.argEnum = enum_val; - - (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, &od ); - return od.optArg.argString; -} - - -/*=export_func optionEnumerationVal - * what: Convert from a string to an enumeration value - * private: - * - * arg: tOptions *, pOpts, the program options descriptor - * arg: tOptDesc *, pOD, enumeration option description - * arg: char const * const *, paz_names, list of enumeration names - * arg: unsigned int, name_ct, number of names in list - * - * ret_type: uintptr_t - * ret_desc: the enumeration value - * - * doc: This converts the optArg.argString string from the option description - * into the index corresponding to an entry in the name list. - * This will match the generated enumeration value. - * Full matches are always accepted. Partial matches are accepted - * if there is only one partial match. -=*/ -uintptr_t -optionEnumerationVal(tOptions * pOpts, tOptDesc * pOD, - char const * const * paz_names, unsigned int name_ct) -{ - uintptr_t res = 0UL; - - /* - * IF the program option descriptor pointer is invalid, - * then it is some sort of special request. - */ - switch ((uintptr_t)pOpts) { - case (uintptr_t)OPTPROC_EMIT_USAGE: - /* - * print the list of enumeration names. - */ - enum_err(pOpts, pOD, paz_names, (int)name_ct); - break; - - case (uintptr_t)OPTPROC_EMIT_SHELL: - { - unsigned int ix = (unsigned int)pOD->optArg.argEnum; - /* - * print the name string. - */ - if (ix >= name_ct) - printf(INVALID_FMT, ix); - else - fputs(paz_names[ ix ], stdout); - - break; - } - - case (uintptr_t)OPTPROC_RETURN_VALNAME: - { - unsigned int ix = (unsigned int)pOD->optArg.argEnum; - /* - * Replace the enumeration value with the name string. - */ - if (ix >= name_ct) - return (uintptr_t)INVALID_STR; - - pOD->optArg.argString = paz_names[ix]; - break; - } - - default: - if ((pOD->fOptState & OPTST_RESET) != 0) - break; - - res = find_name(pOD->optArg.argString, pOpts, pOD, paz_names, name_ct); - - if (pOD->fOptState & OPTST_ALLOC_ARG) { - AGFREE(pOD->optArg.argString); - pOD->fOptState &= ~OPTST_ALLOC_ARG; - pOD->optArg.argString = NULL; - } - } - - return res; -} - -static void -set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, - unsigned int name_ct) -{ - /* - * print the name string. - */ - unsigned int ix = 0; - uintptr_t bits = (uintptr_t)pOD->optCookie; - size_t len = 0; - - (void)pOpts; - bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1; - - while (bits != 0) { - if (bits & 1) { - if (len++ > 0) fputs(OR_STR, stdout); - fputs(paz_names[ix], stdout); - } - if (++ix >= name_ct) break; - bits >>= 1; - } -} - -static void -set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, - unsigned int nm_ct) -{ - char * pz; - uintptr_t mask = (1UL << (uintptr_t)nm_ct) - 1UL; - uintptr_t bits = (uintptr_t)od->optCookie & mask; - unsigned int ix = 0; - size_t len = 1; - - /* - * Replace the enumeration value with the name string. - * First, determine the needed length, then allocate and fill in. - */ - while (bits != 0) { - if (bits & 1) - len += strlen(nm_list[ix]) + PLUS_STR_LEN + 1; - if (++ix >= nm_ct) break; - bits >>= 1; - } - - od->optArg.argString = pz = AGALOC(len, "enum"); - bits = (uintptr_t)od->optCookie & mask; - if (bits == 0) { - *pz = NUL; - return; - } - - for (ix = 0; ; ix++) { - size_t nln; - int doit = bits & 1; - - bits >>= 1; - if (doit == 0) - continue; - - nln = strlen(nm_list[ix]); - memcpy(pz, nm_list[ix], nln); - pz += nln; - if (bits == 0) - break; - memcpy(pz, PLUS_STR, PLUS_STR_LEN); - pz += PLUS_STR_LEN; - } - *pz = NUL; - (void)opts; -} - -/** - * Check membership start conditions. An equal character (@samp{=}) says to - * clear the result and not carry over any residual value. A carat - * (@samp{^}), which may follow the equal character, says to invert the - * result. The scanning pointer is advanced past these characters and any - * leading white space. Invalid sequences are indicated by setting the - * scanning pointer to NULL. - * - * @param od the set membership option description - * @param argp a pointer to the string scanning pointer - * @param invert a pointer to the boolean inversion indicator - * - * @returns either zero or the original value for the optCookie. - */ -static uintptr_t -check_membership_start(tOptDesc * od, char const ** argp, bool * invert) -{ - uintptr_t res = (uintptr_t)od->optCookie; - char const * arg = SPN_WHITESPACE_CHARS(od->optArg.argString); - if ((arg == NULL) || (*arg == NUL)) - goto member_start_fail; - - *invert = false; - - switch (*arg) { - case '=': - res = 0UL; - arg = SPN_WHITESPACE_CHARS(arg + 1); - switch (*arg) { - case '=': case ',': - goto member_start_fail; - case '^': - goto inversion; - default: - break; - } - break; - - case '^': - inversion: - *invert = true; - arg = SPN_WHITESPACE_CHARS(arg + 1); - if (*arg != ',') - break; - /* FALLTHROUGH */ - - case ',': - goto member_start_fail; - - default: - break; - } - - *argp = arg; - return res; - -member_start_fail: - *argp = NULL; - return 0UL; -} - -/** - * convert a name to a bit. Look up a name string to get a bit number - * and shift the value "1" left that number of bits. - * - * @param opts program options descriptor - * @param od the set membership option description - * @param pz address of the start of the bit name - * @param nm_list the list of names for this option - * @param nm_ct the number of entries in this list - * - * @returns 0UL on error, other an unsigned long with the correct bit set. - */ -static uintptr_t -find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, - char const * const * nm_list, unsigned int nm_ct) -{ - char nm_buf[ AO_NAME_SIZE ]; - - memcpy(nm_buf, pz, len); - nm_buf[len] = NUL; - - { - unsigned int shift_ct = (unsigned int) - find_name(nm_buf, opts, od, nm_list, nm_ct); - if (shift_ct >= nm_ct) - return 0UL; - - return 1UL << shift_ct; - } -} - -/*=export_func optionMemberList - * what: Get the list of members of a bit mask set - * - * arg: tOptDesc *, od, the set membership option description - * - * ret_type: char * - * ret_desc: the names of the set bits - * - * doc: This converts the OPT_VALUE_name mask value to a allocated string. - * It is the caller's responsibility to free the string. -=*/ -char * -optionMemberList(tOptDesc * od) -{ - uintptr_t sv = od->optArg.argIntptr; - char * res; - (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); - res = VOIDP(od->optArg.argString); - od->optArg.argIntptr = sv; - return res; -} - -/*=export_func optionSetMembers - * what: Convert between bit flag values and strings - * private: - * - * arg: tOptions *, opts, the program options descriptor - * arg: tOptDesc *, od, the set membership option description - * arg: char const * const *, - * nm_list, list of enumeration names - * arg: unsigned int, nm_ct, number of names in list - * - * doc: This converts the optArg.argString string from the option description - * into the index corresponding to an entry in the name list. - * This will match the generated enumeration value. - * Full matches are always accepted. Partial matches are accepted - * if there is only one partial match. -=*/ -void -optionSetMembers(tOptions * opts, tOptDesc * od, - char const * const * nm_list, unsigned int nm_ct) -{ - /* - * IF the program option descriptor pointer is invalid, - * then it is some sort of special request. - */ - switch ((uintptr_t)opts) { - case (uintptr_t)OPTPROC_EMIT_USAGE: - enum_err(OPTPROC_EMIT_USAGE, od, nm_list, nm_ct); - return; - - case (uintptr_t)OPTPROC_EMIT_SHELL: - set_memb_shell(opts, od, nm_list, nm_ct); - return; - - case (uintptr_t)OPTPROC_RETURN_VALNAME: - set_memb_names(opts, od, nm_list, nm_ct); - return; - - default: - break; - } - - if ((od->fOptState & OPTST_RESET) != 0) - return; - - { - char const * arg; - bool invert; - uintptr_t res = check_membership_start(od, &arg, &invert); - if (arg == NULL) - goto fail_return; - - while (*arg != NUL) { - bool inv_val = false; - int len; - - switch (*arg) { - case ',': - arg = SPN_WHITESPACE_CHARS(arg+1); - if ((*arg == ',') || (*arg == '|')) - goto fail_return; - continue; - - case '-': - case '!': - inv_val = true; - /* FALLTHROUGH */ - - case '+': - case '|': - arg = SPN_WHITESPACE_CHARS(arg+1); - } - - len = (int)(BRK_SET_SEPARATOR_CHARS(arg) - arg); - if (len == 0) - break; - - if ((len == 3) && (strncmp(arg, zAll, 3) == 0)) { - if (inv_val) - res = 0; - else res = ~0UL; - } - else if ((len == 4) && (strncmp(arg, zNone, 4) == 0)) { - if (! inv_val) - res = 0; - } - else do { - char * pz; - uintptr_t bit = strtoul(arg, &pz, 0); - - if (pz != arg + len) { - bit = find_member_bit(opts, od, pz, len, nm_list, nm_ct); - if (bit == 0UL) - goto fail_return; - } - if (inv_val) - res &= ~bit; - else res |= bit; - } while (false); - - arg = SPN_WHITESPACE_CHARS(arg + len); - } - - if (invert) - res ^= ~0UL; - - if (nm_ct < (8 * sizeof(uintptr_t))) - res &= (1UL << nm_ct) - 1UL; - - od->optCookie = VOIDP(res); - } - return; - -fail_return: - od->optCookie = VOIDP(0); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/enum.c */ diff --git a/src/libopts/env.c b/src/libopts/env.c deleted file mode 100644 index 16f0e95..0000000 --- a/src/libopts/env.c +++ /dev/null @@ -1,261 +0,0 @@ - -/** - * \file environment.c - * - * This file contains all of the routines that must be linked into - * an executable to use the generated option processing. The optional - * routines are in separately compiled modules so that they will not - * necessarily be linked in. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/* - * doPrognameEnv - check for preset values from the ${PROGNAME} - * environment variable. This is accomplished by parsing the text into - * tokens, temporarily replacing the arg vector and calling - * immediate_opts and/or regular_opts. - */ -static void -doPrognameEnv(tOptions * pOpts, teEnvPresetType type) -{ - char const * env_opts = getenv(pOpts->pzPROGNAME); - token_list_t * pTL; - int sv_argc; - proc_state_mask_t sv_flag; - char ** sv_argv; - - /* - * No such beast? Then bail now. - */ - if (env_opts == NULL) - return; - - /* - * Tokenize the string. If there's nothing of interest, we'll bail - * here immediately. - */ - pTL = ao_string_tokenize(env_opts); - if (pTL == NULL) - return; - - /* - * Substitute our $PROGNAME argument list for the real one - */ - sv_argc = (int)pOpts->origArgCt; - sv_argv = pOpts->origArgVect; - sv_flag = pOpts->fOptSet; - - /* - * We add a bogus pointer to the start of the list. The program name - * has already been pulled from "argv", so it won't get dereferenced. - * The option scanning code will skip the "program name" at the start - * of this list of tokens, so we accommodate this way .... - */ - { - uintptr_t v = (uintptr_t)(pTL->tkn_list); - pOpts->origArgVect = VOIDP(v - sizeof(char *)); - } - pOpts->origArgCt = (unsigned int)pTL->tkn_ct + 1; - pOpts->fOptSet &= ~OPTPROC_ERRSTOP; - - pOpts->curOptIdx = 1; - pOpts->pzCurOpt = NULL; - - switch (type) { - case ENV_IMM: - (void)immediate_opts(pOpts); - break; - - case ENV_ALL: - (void)immediate_opts(pOpts); - pOpts->curOptIdx = 1; - pOpts->pzCurOpt = NULL; - /* FALLTHROUGH */ - - case ENV_NON_IMM: - (void)regular_opts(pOpts); - } - - /* - * Free up the temporary arg vector and restore the original program args. - */ - free(pTL); - pOpts->origArgVect = sv_argv; - pOpts->origArgCt = (unsigned int)sv_argc; - pOpts->fOptSet = sv_flag; -} - -static void -do_env_opt(tOptState * os, char * env_name, - tOptions * pOpts, teEnvPresetType type) -{ - os->pzOptArg = getenv(env_name); - if (os->pzOptArg == NULL) - return; - - os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState; - os->optType = TOPT_UNDEFINED; - - if ( (os->pOD->pz_DisablePfx != NULL) - && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) { - os->flags |= OPTST_DISABLED; - os->pzOptArg = NULL; - handle_opt(pOpts, os); - return; - } - - switch (type) { - case ENV_IMM: - /* - * Process only immediate actions - */ - if (DO_IMMEDIATELY(os->flags)) - break; - return; - - case ENV_NON_IMM: - /* - * Process only NON immediate actions - */ - if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags)) - break; - return; - - default: /* process everything */ - break; - } - - /* - * Make sure the option value string is persistent and consistent. - * - * The interpretation of the option value depends - * on the type of value argument the option takes - */ - if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) { - /* - * Ignore any value. - */ - os->pzOptArg = NULL; - - } else if (os->pzOptArg[0] == NUL) { - /* - * If the argument is the empty string and the argument is - * optional, then treat it as if the option was not specified. - */ - if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0) - return; - os->pzOptArg = NULL; - - } else { - AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument"); - os->flags |= OPTST_ALLOC_ARG; - } - - handle_opt(pOpts, os); -} - -/* - * env_presets - check for preset values from the envrionment - * This routine should process in all, immediate or normal modes.... - */ -static void -env_presets(tOptions * pOpts, teEnvPresetType type) -{ - int ct; - tOptState st; - char * pzFlagName; - size_t spaceLeft; - char zEnvName[ AO_NAME_SIZE ]; - - /* - * Finally, see if we are to look at the environment - * variables for initial values. - */ - if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0) - return; - - doPrognameEnv(pOpts, type); - - ct = pOpts->presetOptCt; - st.pOD = pOpts->pOptDesc; - - pzFlagName = zEnvName - + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME); - spaceLeft = AO_NAME_SIZE - (unsigned long)(pzFlagName - zEnvName) - 1; - - for (;ct-- > 0; st.pOD++) { - size_t nln; - - /* - * If presetting is disallowed, then skip this entry - */ - if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0) - || (st.pOD->optEquivIndex != NO_EQUIVALENT) ) - continue; - - /* - * IF there is no such environment variable, - * THEN skip this entry, too. - */ - nln = strlen(st.pOD->pz_NAME) + 1; - if (nln <= spaceLeft) { - /* - * Set up the option state - */ - memcpy(pzFlagName, st.pOD->pz_NAME, nln); - do_env_opt(&st, zEnvName, pOpts, type); - } - } - - /* - * Special handling for ${PROGNAME_LOAD_OPTS} - */ - if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) - && (pOpts->specOptIdx.save_opts != 0)) { - size_t nln; - st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; - - if (st.pOD->pz_NAME == NULL) - return; - - nln = strlen(st.pOD->pz_NAME) + 1; - - if (nln > spaceLeft) - return; - - memcpy(pzFlagName, st.pOD->pz_NAME, nln); - do_env_opt(&st, zEnvName, pOpts, type); - } -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/environment.c */ diff --git a/src/libopts/file.c b/src/libopts/file.c deleted file mode 100644 index 14efe8f..0000000 --- a/src/libopts/file.c +++ /dev/null @@ -1,201 +0,0 @@ - -/** - * \file file.c - * - * Handle options that have file names for arguments. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * Make sure the directory containing the subject file exists and that - * the file exists or does not exist, per the option requirements. - * - * @param ftype file existence type flags - * @param pOpts program option descriptor - * @param pOD the option descriptor - */ -static void -check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD) -{ - char const * fname = pOD->optArg.argString; - struct stat sb; - - errno = 0; - - switch (ftype & FTYPE_MODE_EXIST_MASK) { - case FTYPE_MODE_MUST_NOT_EXIST: - if ((stat(fname, &sb) == 0) || (errno != ENOENT)) { - if (errno == 0) - errno = EINVAL; - fserr_exit(pOpts->pzProgName, "stat", fname); - /* NOTREACHED */ - } - /* FALLTHROUGH */ - - default: - case FTYPE_MODE_MAY_EXIST: - { - char * p = strrchr(fname, DIRCH); - size_t l; - - if (p == NULL) - /* - * The file may or may not exist and its directory is ".". - * Assume that "." exists. - */ - break; - - l = (size_t)(p - fname); - p = AGALOC(l + 1, "fname"); - memcpy(p, fname, l); - p[l] = NUL; - - if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode))) - fserr_exit(pOpts->pzProgName, "stat", p); - /* NOTREACHED */ - - AGFREE(p); - break; - } - - case FTYPE_MODE_MUST_EXIST: - if ( (stat(fname, &sb) != 0) - || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) - fserr_exit(pOpts->pzProgName, "stat", fname); - /* NOTREACHED */ - - break; - } -} - -/** - * Open the specified file with open(2) and save the FD. - * - * @param pOpts program option descriptor - * @param pOD the option descriptor - * @param mode the open mode (uses int flags value) - */ -static void -open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) -{ - int fd = open(pOD->optArg.argString, mode.file_flags); - if (fd < 0) - fserr_exit(pOpts->pzProgName, "open", pOD->optArg.argString); - /* NOTREACHED */ - - if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) - pOD->optCookie = VOIDP(pOD->optArg.argString); - else - AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); - - pOD->optArg.argFd = fd; - pOD->fOptState &= ~OPTST_ALLOC_ARG; -} - -/** - * Open the specified file with open(2) and save the FD. - * - * @param pOpts program option descriptor - * @param pOD the option descriptor - * @param mode the open mode (uses "char *" mode value) - */ -static void -fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) -{ - FILE * fp = fopen(pOD->optArg.argString, mode.file_mode); - if (fp == NULL) - fserr_exit(pOpts->pzProgName, "fopen", pOD->optArg.argString); - /* NOTREACHED */ - - if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) - pOD->optCookie = VOIDP(pOD->optArg.argString); - else - AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); - - pOD->optArg.argFp = fp; - pOD->fOptState &= ~OPTST_ALLOC_ARG; -} - -/*=export_func optionFileCheck - * private: - * - * what: Decipher a boolean value - * arg: + tOptions * + pOpts + program options descriptor + - * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + - * arg: + teOptFileType + ftype + File handling type + - * arg: + tuFileMode + mode + file open mode (if needed) + - * - * doc: - * Make sure the named file conforms with the file type mode. - * The mode specifies if the file must exist, must not exist or may - * (or may not) exist. The mode may also specify opening the - * file: don't, open just the descriptor (fd), or open as a stream - * (FILE * pointer). -=*/ -void -optionFileCheck(tOptions * pOpts, tOptDesc * pOD, - teOptFileType ftype, tuFileMode mode) -{ - if (pOpts <= OPTPROC_EMIT_LIMIT) { - if (pOpts != OPTPROC_EMIT_USAGE) - return; - - switch (ftype & FTYPE_MODE_EXIST_MASK) { - case FTYPE_MODE_MUST_NOT_EXIST: - fputs(zFileCannotExist + tab_skip_ct, option_usage_fp); - break; - - case FTYPE_MODE_MUST_EXIST: - fputs(zFileMustExist + tab_skip_ct, option_usage_fp); - break; - } - return; - } - - if ((pOD->fOptState & OPTST_RESET) != 0) { - if (pOD->optCookie != NULL) - AGFREE(pOD->optCookie); - return; - } - - check_existence(ftype, pOpts, pOD); - - switch (ftype & FTYPE_MODE_OPEN_MASK) { - default: - case FTYPE_MODE_NO_OPEN: break; - case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break; - case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break; - } -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/file.c */ diff --git a/src/libopts/find.c b/src/libopts/find.c deleted file mode 100644 index 03ae103..0000000 --- a/src/libopts/find.c +++ /dev/null @@ -1,765 +0,0 @@ -/** - * @file check.c - * - * @brief Hunt for options in the option descriptor list - * - * This file contains the routines that deal with processing quoted strings - * into an internal format. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * find the name and name length we are looking for - */ -static int -parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) -{ - int res = 0; - char const * p = *nm_pp; - *arg_pp = NULL; - - for (;;) { - switch (*(p++)) { - case NUL: return res; - - case '=': - memcpy(buf, *nm_pp, (size_t)res); - - buf[res] = NUL; - *nm_pp = buf; - *arg_pp = (char *)p; - return res; - - default: - if (++res >= (int)bufsz) - return -1; - } - } -} - -/** - * print out the options that match the given name. - * - * @param pOpts option data - * @param opt_name name of option to look for - */ -static void -opt_ambiguities(tOptions * opts, char const * name, int nm_len) -{ - char const * const hyph = - NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER; - - tOptDesc * pOD = opts->pOptDesc; - int idx = 0; - - fputs(zambig_list_msg, stderr); - do { - if (pOD->pz_Name == NULL) - continue; /* doc option */ - - if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) - fprintf(stderr, zambig_file, hyph, pOD->pz_Name); - - else if ( (pOD->pz_DisableName != NULL) - && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) - ) - fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName); - } while (pOD++, (++idx < opts->optCt)); -} - -/** - * Determine the number of options that match the name - * - * @param pOpts option data - * @param opt_name name of option to look for - * @param nm_len length of provided name - * @param index pointer to int for option index - * @param disable pointer to bool to mark disabled option - * @return count of options that match - */ -static int -opt_match_ct(tOptions * opts, char const * name, int nm_len, - int * ixp, bool * disable) -{ - int matchCt = 0; - int idx = 0; - int idxLim = opts->optCt; - tOptDesc * pOD = opts->pOptDesc; - - do { - /* - * If option disabled or a doc option, skip to next - */ - if (pOD->pz_Name == NULL) - continue; - - if ( SKIP_OPT(pOD) - && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT))) - continue; - - if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) { - /* - * IF we have a complete match - * THEN it takes priority over any already located partial - */ - if (pOD->pz_Name[ nm_len ] == NUL) { - *ixp = idx; - return 1; - } - } - - /* - * IF there is a disable name - * *AND* the option name matches the disable name - * THEN ... - */ - else if ( (pOD->pz_DisableName != NULL) - && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) - ) { - *disable = true; - - /* - * IF we have a complete match - * THEN it takes priority over any already located partial - */ - if (pOD->pz_DisableName[ nm_len ] == NUL) { - *ixp = idx; - return 1; - } - } - - else - continue; /* does not match any option */ - - /* - * We found a full or partial match, either regular or disabling. - * Remember the index for later. - */ - *ixp = idx; - ++matchCt; - - } while (pOD++, (++idx < idxLim)); - - return matchCt; -} - -/** - * Set the option to the indicated option number. - * - * @param opts option data - * @param arg option argument (if glued to name) - * @param idx option index - * @param disable mark disabled option - * @param st state about current option - */ -static tSuccess -opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st) -{ - tOptDesc * pOD = opts->pOptDesc + idx; - - if (SKIP_OPT(pOD)) { - if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) - return FAILURE; - - fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name); - if (pOD->pzText != NULL) - fprintf(stderr, SET_OFF_FMT, pOD->pzText); - fputc(NL, stderr); - (*opts->pUsageProc)(opts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - - /* - * IF we found a disablement name, - * THEN set the bit in the callers' flag word - */ - if (disable) - st->flags |= OPTST_DISABLED; - - st->pOD = pOD; - st->pzOptArg = arg; - st->optType = TOPT_LONG; - - return SUCCESS; -} - -/** - * An option was not found. Check for default option and set it - * if there is one. Otherwise, handle the error. - * - * @param opts option data - * @param name name of option to look for - * @param arg option argument - * @param st state about current option - * - * @return success status - */ -static tSuccess -opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st) -{ - /* - * IF there is no equal sign - * *AND* we are using named arguments - * *AND* there is a default named option, - * THEN return that option. - */ - if ( (arg == NULL) - && NAMED_OPTS(opts) - && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) { - - st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt; - st->pzOptArg = name; - st->optType = TOPT_DEFAULT; - return SUCCESS; - } - - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { - fprintf(stderr, zIllOptStr, opts->pzProgPath, name); - (*opts->pUsageProc)(opts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - - return FAILURE; -} - -/** - * Several options match the provided name. - * - * @param opts option data - * @param name name of option to look for - * @param match_ct number of matching options - * - * @return success status (always FAILURE, if it returns) - */ -static tSuccess -opt_ambiguous(tOptions * opts, char const * name, int match_ct) -{ - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { - fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct); - if (match_ct <= 4) - opt_ambiguities(opts, name, (int)strlen(name)); - (*opts->pUsageProc)(opts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - return FAILURE; -} - -/*=export_func optionVendorOption - * private: - * - * what: Process a vendor option - * arg: + tOptions * + pOpts + program options descriptor + - * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + - * - * doc: - * For POSIX specified utilities, the options are constrained to the options, - * @xref{config attributes, Program Configuration}. AutoOpts clients should - * never specify this directly. It gets referenced when the option - * definitions contain a "vendor-opt" attribute. -=*/ -void -optionVendorOption(tOptions * pOpts, tOptDesc * pOD) -{ - tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); - char const * vopt_str = pOD->optArg.argString; - - if (pOpts <= OPTPROC_EMIT_LIMIT) - return; - - if ((pOD->fOptState & OPTST_RESET) != 0) - return; - - if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) - opt_st.flags = OPTST_DEFINED; - - if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0) - || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) - || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) - { - fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); - (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - - /* - * See if we are in immediate handling state. - */ - if (pOpts->fOptSet & OPTPROC_IMMEDIATE) { - /* - * See if the enclosed option is okay with that state. - */ - if (DO_IMMEDIATELY(opt_st.flags)) - (void)handle_opt(pOpts, &opt_st); - - } else { - /* - * non-immediate direction. - * See if the enclosed option is okay with that state. - */ - if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags)) - (void)handle_opt(pOpts, &opt_st); - } -} - -/** - * Find the option descriptor by full name. - * - * @param opts option data - * @param opt_name name of option to look for - * @param state state about current option - * - * @return success status - */ -static tSuccess -opt_find_long(tOptions * opts, char const * opt_name, tOptState * state) -{ - char name_buf[128]; - char * opt_arg; - int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf)); - - int idx = 0; - bool disable = false; - int ct; - - if (nm_len <= 1) { - if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) - return FAILURE; - - fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name); - (*opts->pUsageProc)(opts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - - ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable); - - /* - * See if we found one match, no matches or multiple matches. - */ - switch (ct) { - case 1: return opt_set(opts, opt_arg, idx, disable, state); - case 0: return opt_unknown(opts, opt_name, opt_arg, state); - default: return opt_ambiguous(opts, opt_name, ct); - } -} - - -/** - * Find the short option descriptor for the current option - * - * @param pOpts option data - * @param optValue option flag character - * @param pOptState state about current option - */ -static tSuccess -opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState) -{ - tOptDesc * pRes = pOpts->pOptDesc; - int ct = pOpts->optCt; - - /* - * Search the option list - */ - do { - if (optValue != pRes->optValue) - continue; - - if (SKIP_OPT(pRes)) { - if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) - && (pRes->pz_Name != NULL)) { - if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) - return FAILURE; - - fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name); - if (pRes->pzText != NULL) - fprintf(stderr, SET_OFF_FMT, pRes->pzText); - fputc(NL, stderr); - (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - goto short_opt_error; - } - - pOptState->pOD = pRes; - pOptState->optType = TOPT_SHORT; - return SUCCESS; - - } while (pRes++, --ct > 0); - - /* - * IF the character value is a digit - * AND there is a special number option ("-n") - * THEN the result is the "option" itself and the - * option is the specially marked "number" option. - */ - if ( IS_DEC_DIGIT_CHAR(optValue) - && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { - pOptState->pOD = \ - pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; - (pOpts->pzCurOpt)--; - pOptState->optType = TOPT_SHORT; - return SUCCESS; - } - - short_opt_error: - - /* - * IF we are to stop on errors (the default, actually) - * THEN call the usage procedure. - */ - if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { - fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue); - (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - _exit(EXIT_FAILURE); /* to be certain */ - } - - return FAILURE; -} - -/** - * Process option with a required argument. Long options can either have a - * separate command line argument, or an argument attached by the '=' - * character. Figure out which. - * - * @param[in,out] opts the program option descriptor - * @param[in,out] o_st the option processing state - * @returns SUCCESS or FAILURE - */ -static tSuccess -get_opt_arg_must(tOptions * opts, tOptState * o_st) -{ - switch (o_st->optType) { - case TOPT_SHORT: - /* - * See if an arg string follows the flag character - */ - if (*++(opts->pzCurOpt) == NUL) - opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ]; - o_st->pzOptArg = opts->pzCurOpt; - break; - - case TOPT_LONG: - /* - * See if an arg string has already been assigned (glued on - * with an `=' character) - */ - if (o_st->pzOptArg == NULL) - o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ]; - break; - - default: -#ifdef DEBUG - fputs("AutoOpts lib error: option type not selected\n", stderr); - option_exits(EXIT_FAILURE); -#endif - - case TOPT_DEFAULT: - /* - * The option was selected by default. The current token is - * the option argument. - */ - break; - } - - /* - * Make sure we did not overflow the argument list. - */ - if (opts->curOptIdx > opts->origArgCt) { - fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name); - return FAILURE; - } - - opts->pzCurOpt = NULL; /* next time advance to next arg */ - return SUCCESS; -} - -/** - * Process an option with an optional argument. For short options, it looks - * at the character after the option character, or it consumes the next full - * argument. For long options, it looks for an '=' character attachment to - * the long option name before deciding to take the next command line - * argument. - * - * @param pOpts the option descriptor - * @param o_st a structure for managing the current processing state - * @returns SUCCESS or does not return - */ -static tSuccess -get_opt_arg_may(tOptions * pOpts, tOptState * o_st) -{ - /* - * An option argument is optional. - */ - switch (o_st->optType) { - case TOPT_SHORT: - if (*++pOpts->pzCurOpt != NUL) - o_st->pzOptArg = pOpts->pzCurOpt; - else { - char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; - - /* - * BECAUSE it is optional, we must make sure - * we did not find another flag and that there - * is such an argument. - */ - if ((pzLA == NULL) || (*pzLA == '-')) - o_st->pzOptArg = NULL; - else { - pOpts->curOptIdx++; /* argument found */ - o_st->pzOptArg = pzLA; - } - } - break; - - case TOPT_LONG: - /* - * Look for an argument if we don't already have one (glued on - * with a `=' character) *AND* we are not in named argument mode - */ - if ( (o_st->pzOptArg == NULL) - && (! NAMED_OPTS(pOpts))) { - char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; - - /* - * BECAUSE it is optional, we must make sure - * we did not find another flag and that there - * is such an argument. - */ - if ((pzLA == NULL) || (*pzLA == '-')) - o_st->pzOptArg = NULL; - else { - pOpts->curOptIdx++; /* argument found */ - o_st->pzOptArg = pzLA; - } - } - break; - - default: - case TOPT_DEFAULT: - ao_bug(zbad_default_msg); - } - - /* - * After an option with an optional argument, we will - * *always* start with the next option because if there - * were any characters following the option name/flag, - * they would be interpreted as the argument. - */ - pOpts->pzCurOpt = NULL; - return SUCCESS; -} - -/** - * Process option that does not have an argument. - * - * @param[in,out] opts the program option descriptor - * @param[in,out] o_st the option processing state - * @returns SUCCESS or FAILURE - */ -static tSuccess -get_opt_arg_none(tOptions * pOpts, tOptState * o_st) -{ - /* - * No option argument. Make sure next time around we find - * the correct option flag character for short options - */ - if (o_st->optType == TOPT_SHORT) - (pOpts->pzCurOpt)++; - - /* - * It is a long option. Make sure there was no ``=xxx'' argument - */ - else if (o_st->pzOptArg != NULL) { - fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name); - return FAILURE; - } - - /* - * It is a long option. Advance to next command line argument. - */ - else - pOpts->pzCurOpt = NULL; - - return SUCCESS; -} - -/** - * Process option. Figure out whether or not to look for an option argument. - * - * @param[in,out] opts the program option descriptor - * @param[in,out] o_st the option processing state - * @returns SUCCESS or FAILURE - */ -static tSuccess -get_opt_arg(tOptions * opts, tOptState * o_st) -{ - o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK); - - /* - * Disabled options and options specified to not have arguments - * are handled with the "none" procedure. Otherwise, check the - * optional flag and call either the "may" or "must" function. - */ - if ((o_st->flags & OPTST_DISABLED) != 0) - return get_opt_arg_none(opts, o_st); - - switch (OPTST_GET_ARGTYPE(o_st->flags)) { - case OPARG_TYPE_STATIC: - { - /* - * Propagate the static arg - */ - tSuccess res = get_opt_arg_none(opts, o_st); - o_st->pzOptArg = o_st->pOD->optArg.argString; - return res; - } - - case OPARG_TYPE_NONE: - return get_opt_arg_none(opts, o_st); - } - - if (o_st->flags & OPTST_ARG_OPTIONAL) - return get_opt_arg_may( opts, o_st); - - return get_opt_arg_must(opts, o_st); -} - -/** - * Find the option descriptor for the current option. - * - * @param[in,out] opts the program option descriptor - * @param[in,out] o_st the option processing state - * @returns SUCCESS or FAILURE - */ -static tSuccess -find_opt(tOptions * opts, tOptState * o_st) -{ - /* - * IF we are continuing a short option list (e.g. -xyz...) - * THEN continue a single flag option. - * OTHERWISE see if there is room to advance and then do so. - */ - if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL)) - return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); - - if (opts->curOptIdx >= opts->origArgCt) - return PROBLEM; /* NORMAL COMPLETION */ - - opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ]; - - /* - * IF all arguments must be named options, ... - */ - if (NAMED_OPTS(opts)) { - char * pz = opts->pzCurOpt; - int def; - tSuccess res; - uint16_t * def_opt; - - opts->curOptIdx++; - - if (*pz != '-') - return opt_find_long(opts, pz, o_st); - - /* - * The name is prefixed with one or more hyphens. Strip them off - * and disable the "default_opt" setting. Use heavy recasting to - * strip off the "const" quality of the "default_opt" field. - */ - while (*(++pz) == '-') ; - def_opt = VOIDP(&(opts->specOptIdx.default_opt)); - def = *def_opt; - *def_opt = NO_EQUIVALENT; - res = opt_find_long(opts, pz, o_st); - *def_opt = (uint16_t)def; - return res; - } - - /* - * Note the kind of flag/option marker - */ - if (*((opts->pzCurOpt)++) != '-') - return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ - - /* - * Special hack for a hyphen by itself - */ - if (*(opts->pzCurOpt) == NUL) - return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ - - /* - * The current argument is to be processed as an option argument - */ - opts->curOptIdx++; - - /* - * We have an option marker. - * Test the next character for long option indication - */ - if (opts->pzCurOpt[0] == '-') { - if (*++(opts->pzCurOpt) == NUL) - /* - * NORMAL COMPLETION - NOT this arg, but rest are operands - */ - return PROBLEM; - - /* - * We do not allow the hyphen to be used as a flag value. - * Therefore, if long options are not to be accepted, we punt. - */ - if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) { - fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2); - return FAILURE; - } - - return opt_find_long(opts, opts->pzCurOpt, o_st); - } - - /* - * If short options are not allowed, then do long - * option processing. Otherwise the character must be a - * short (i.e. single character) option. - */ - if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0) - return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); - - return opt_find_long(opts, opts->pzCurOpt, o_st); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/find.c */ diff --git a/src/libopts/genshell.c b/src/libopts/genshell.c deleted file mode 100644 index 05182a6..0000000 --- a/src/libopts/genshell.c +++ /dev/null @@ -1,848 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (genshell.c) - * - * It has been AutoGen-ed - * From the definitions genshell.def - * and the template file options - * - * Generated from AutoOpts 42:1:17 templates. - * - * AutoOpts is a copyrighted work. This source file is not encumbered - * by AutoOpts licensing, but is provided under the licensing terms chosen - * by the genshellopt author or copyright holder. AutoOpts is - * licensed under the terms of the LGPL. The redistributable library - * (``libopts'') is licensed under the terms of either the LGPL or, at the - * users discretion, the BSD license. See the AutoOpts and/or libopts sources - * for details. - * - * The genshellopt program is copyrighted and licensed - * under the following terms: - * - * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. - * This is free software. It is licensed for use, modification and - * redistribution under the terms of the GNU Lesser General Public License, - * version 2 or later - * - * The genshellopt library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see - * - */ - -#ifndef __doxygen__ -#define OPTION_CODE_COMPILE 1 -#include "genshell.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -extern FILE * option_usage_fp; -#define zCopyright (genshellopt_opt_strs+0) -#define zLicenseDescrip (genshellopt_opt_strs+285) - -extern tUsageProc genshelloptUsage; - -#ifndef NULL -# define NULL 0 -#endif - -/** - * static const strings for genshellopt options - */ -static char const genshellopt_opt_strs[1769] = -/* 0 */ "genshellopt 1\n" - "Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n" - "This is free software. It is licensed for use, modification and\n" - "redistribution under the terms of the GNU Lesser General Public License,\n" - "version 2 or later \n\0" -/* 285 */ "The genshellopt library is free software; you can redistribute it and/or\n" - "modify it under the terms of the GNU Library General Public License as\n" - "published by the Free Software Foundation; either version 2 of the License,\n" - "or (at your option) any later version.\n\n" - "This library is distributed in the hope that it will be useful, but WITHOUT\n" - "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" - "FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n" - "License for more details.\n\n" - "You should have received a copy of the GNU Library General Public License\n" - "along with this library; if not, see\n" - "\n\0" -/* 957 */ "Output Script File\0" -/* 976 */ "SCRIPT\0" -/* 983 */ "script\0" -/* 990 */ "Shell name (follows \"#!\" magic)\0" -/* 1022 */ "SHELL\0" -/* 1028 */ "no-shell\0" -/* 1037 */ "no\0" -/* 1040 */ "display extended usage information and exit\0" -/* 1084 */ "help\0" -/* 1089 */ "extended usage information passed thru pager\0" -/* 1134 */ "more-help\0" -/* 1144 */ "output version information and exit\0" -/* 1180 */ "version\0" -/* 1188 */ "GENSHELLOPT\0" -/* 1200 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n" - "Usage: %s [ - [] | --[{=| }] ]...\n\0" -/* 1321 */ "autogen-users@lists.sourceforge.net\0" -/* 1357 */ "Note that 'shell' is only useful if the output file does not already exist.\n" - "If it does, then the shell name and optional first argument will be\n" - "extracted from the script file.\n\0" -/* 1534 */ "If the script file already exists and contains Automated Option Processing\n" - "text, the second line of the file through the ending tag will be replaced\n" - "by the newly generated text. The first '#!' line will be regenerated.\n\0" -/* 1755 */ "genshellopt 1"; - -/** - * script option description: - */ -/** Descriptive text for the script option */ -#define SCRIPT_DESC (genshellopt_opt_strs+957) -/** Upper-cased name for the script option */ -#define SCRIPT_NAME (genshellopt_opt_strs+976) -/** Name string for the script option */ -#define SCRIPT_name (genshellopt_opt_strs+983) -/** Compiled in flag settings for the script option */ -#define SCRIPT_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) - -/** - * shell option description: - */ -/** Descriptive text for the shell option */ -#define SHELL_DESC (genshellopt_opt_strs+990) -/** Upper-cased name for the shell option */ -#define SHELL_NAME (genshellopt_opt_strs+1022) -/** disablement name for the shell option */ -#define NOT_SHELL_name (genshellopt_opt_strs+1028) -/** disablement prefix for the shell option */ -#define NOT_SHELL_PFX (genshellopt_opt_strs+1037) -/** Name string for the shell option */ -#define SHELL_name (NOT_SHELL_name + 3) -/** Compiled in flag settings for the shell option */ -#define SHELL_FLAGS (OPTST_INITENABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) - -/* - * Help/More_Help/Version option descriptions: - */ -#define HELP_DESC (genshellopt_opt_strs+1040) -#define HELP_name (genshellopt_opt_strs+1084) -#ifdef HAVE_WORKING_FORK -#define MORE_HELP_DESC (genshellopt_opt_strs+1089) -#define MORE_HELP_name (genshellopt_opt_strs+1134) -#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) -#else -#define MORE_HELP_DESC HELP_DESC -#define MORE_HELP_name HELP_name -#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) -#endif -#ifdef NO_OPTIONAL_OPT_ARGS -# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) -#else -# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ - OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) -#endif -#define VER_DESC (genshellopt_opt_strs+1144) -#define VER_name (genshellopt_opt_strs+1180) -/** - * Declare option callback procedures - */ -extern tOptProc - optionBooleanVal, optionNestedVal, optionNumericVal, - optionPagedUsage, optionPrintVersion, optionResetOpt, - optionStackArg, optionTimeDate, optionTimeVal, - optionUnstackArg, optionVendorOption; -static tOptProc - doUsageOpt; -#define VER_PROC optionPrintVersion - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** - * Define the genshellopt Option Descriptions. - * This is an array of GENSHELL_OPTION_CT entries, one for each - * option that the genshellopt program responds to. - */ -static tOptDesc optDesc[GENSHELL_OPTION_CT] = { - { /* entry idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, - /* equiv idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, - /* equivalenced to */ NO_EQUIVALENT, - /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ SCRIPT_FLAGS, 0, - /* last opt argumnt */ { NULL }, /* --script */ - /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, NULL, - /* option proc */ NULL, - /* desc, NAME, name */ SCRIPT_DESC, SCRIPT_NAME, SCRIPT_name, - /* disablement strs */ NULL, NULL }, - - { /* entry idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, - /* equiv idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, - /* equivalenced to */ NO_EQUIVALENT, - /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ SHELL_FLAGS, 0, - /* last opt argumnt */ { NULL }, /* --shell */ - /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, NULL, - /* option proc */ NULL, - /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name, - /* disablement strs */ NOT_SHELL_name, NOT_SHELL_PFX }, - - { /* entry idx, value */ INDEX_GENSHELL_OPT_VERSION, VALUE_GENSHELL_OPT_VERSION, - /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_VERSION, - /* equivalenced to */ NO_EQUIVALENT, - /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ VER_FLAGS, AOUSE_VERSION, - /* last opt argumnt */ { NULL }, - /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, NULL, - /* option proc */ VER_PROC, - /* desc, NAME, name */ VER_DESC, NULL, VER_name, - /* disablement strs */ NULL, NULL }, - - - - { /* entry idx, value */ INDEX_GENSHELL_OPT_HELP, VALUE_GENSHELL_OPT_HELP, - /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_HELP, - /* equivalenced to */ NO_EQUIVALENT, - /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, - /* last opt argumnt */ { NULL }, - /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, NULL, - /* option proc */ doUsageOpt, - /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, - /* disablement strs */ NULL, NULL }, - - { /* entry idx, value */ INDEX_GENSHELL_OPT_MORE_HELP, VALUE_GENSHELL_OPT_MORE_HELP, - /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_MORE_HELP, - /* equivalenced to */ NO_EQUIVALENT, - /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, - /* last opt argumnt */ { NULL }, - /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, NULL, - /* option proc */ optionPagedUsage, - /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, - /* disablement strs */ NULL, NULL } -}; - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** Reference to the upper cased version of genshellopt. */ -#define zPROGNAME (genshellopt_opt_strs+1188) -/** Reference to the title line for genshellopt usage. */ -#define zUsageTitle (genshellopt_opt_strs+1200) -/** There is no genshellopt configuration file. */ -#define zRcName NULL -/** There are no directories to search for genshellopt config files. */ -#define apzHomeList NULL -/** The genshellopt program bug email address. */ -#define zBugsAddr (genshellopt_opt_strs+1321) -/** Clarification/explanation of what genshellopt does. */ -#define zExplain (genshellopt_opt_strs+1357) -/** Extra detail explaining what genshellopt does. */ -#define zDetail (genshellopt_opt_strs+1534) -/** The full version string for genshellopt. */ -#define zFullVersion (genshellopt_opt_strs+1755) -/* extracted from optcode.tlib near line 342 */ - -#if defined(ENABLE_NLS) -# define OPTPROC_BASE OPTPROC_TRANSLATE - static tOptionXlateProc translate_option_strings; -#else -# define OPTPROC_BASE OPTPROC_NONE -# define translate_option_strings NULL -#endif /* ENABLE_NLS */ - -#define genshellopt_full_usage (NULL) -#define genshellopt_short_usage (NULL) - -#endif /* not defined __doxygen__ */ - -/* - * Create the static procedure(s) declared above. - */ -/** - * The callout function that invokes the genshelloptUsage function. - * - * @param[in] opts the AutoOpts option description structure - * @param[in] od the descriptor for the "help" (usage) option. - * @noreturn - */ -static void -doUsageOpt(tOptions * opts, tOptDesc * od) -{ - int ex_code; - ex_code = GENSHELLOPT_EXIT_SUCCESS; - genshelloptUsage(&genshelloptOptions, ex_code); - /* NOTREACHED */ - exit(GENSHELLOPT_EXIT_FAILURE); - (void)opts; - (void)od; -} -/* extracted from optmain.tlib near line 1250 */ - -/** - * The directory containing the data associated with genshellopt. - */ -#ifndef PKGDATADIR -# define PKGDATADIR "" -#endif - -/** - * Information about the person or institution that packaged genshellopt - * for the current distribution. - */ -#ifndef WITH_PACKAGER -# define genshellopt_packager_info NULL -#else -/** Packager information for genshellopt. */ -static char const genshellopt_packager_info[] = - "Packaged by " WITH_PACKAGER - -# ifdef WITH_PACKAGER_VERSION - " ("WITH_PACKAGER_VERSION")" -# endif - -# ifdef WITH_PACKAGER_BUG_REPORTS - "\nReport genshellopt bugs to " WITH_PACKAGER_BUG_REPORTS -# endif - "\n"; -#endif -#ifndef __doxygen__ - -#endif /* __doxygen__ */ -/** - * The option definitions for genshellopt. The one structure that - * binds them all. - */ -tOptions genshelloptOptions = { - OPTIONS_STRUCT_VERSION, - 0, NULL, /* original argc + argv */ - ( OPTPROC_BASE - + OPTPROC_ERRSTOP - + OPTPROC_SHORTOPT - + OPTPROC_LONGOPT - + OPTPROC_NO_REQ_OPT - + OPTPROC_NEGATIONS - + OPTPROC_NO_ARGS ), - 0, NULL, /* current option index, current option */ - NULL, NULL, zPROGNAME, - zRcName, zCopyright, zLicenseDescrip, - zFullVersion, apzHomeList, zUsageTitle, - zExplain, zDetail, optDesc, - zBugsAddr, /* address to send bugs to */ - NULL, NULL, /* extensions/saved state */ - genshelloptUsage, /* usage procedure */ - translate_option_strings, /* translation procedure */ - /* - * Indexes to special options - */ - { INDEX_GENSHELL_OPT_MORE_HELP, /* more-help option index */ - NO_EQUIVALENT, /* save option index */ - NO_EQUIVALENT, /* '-#' option index */ - NO_EQUIVALENT /* index of default opt */ - }, - 5 /* full option count */, 2 /* user option count */, - genshellopt_full_usage, genshellopt_short_usage, - NULL, NULL, - PKGDATADIR, genshellopt_packager_info -}; - -#if ENABLE_NLS -/** - * This code is designed to translate translatable option text for the - * genshellopt program. These translations happen upon entry - * to optionProcess(). - */ -#include -#include -#include -#include -#ifdef HAVE_DCGETTEXT -# include -#endif -#include - -static char * AO_gettext(char const * pz); -static void coerce_it(void ** s); - -/** - * AutoGen specific wrapper function for gettext. It relies on the macro _() - * to convert from English to the target language, then strdup-duplicates the - * result string. It tries the "libopts" domain first, then whatever has been - * set via the \a textdomain(3) call. - * - * @param[in] pz the input text used as a lookup key. - * @returns the translated text (if there is one), - * or the original text (if not). - */ -static char * -AO_gettext(char const * pz) -{ - char * res; - if (pz == NULL) - return NULL; -#ifdef HAVE_DCGETTEXT - /* - * While processing the option_xlateable_txt data, try to use the - * "libopts" domain. Once we switch to the option descriptor data, - * do *not* use that domain. - */ - if (option_xlateable_txt.field_ct != 0) { - res = dgettext("libopts", pz); - if (res == pz) - res = (char *)VOIDP(_(pz)); - } else - res = (char *)VOIDP(_(pz)); -#else - res = (char *)VOIDP(_(pz)); -#endif - if (res == pz) - return res; - res = strdup(res); - if (res == NULL) { - fputs(_("No memory for duping translated strings\n"), stderr); - exit(GENSHELLOPT_EXIT_FAILURE); - } - return res; -} - -/** - * All the pointers we use are marked "* const", but they are stored in - * writable memory. Coerce the mutability and set the pointer. - */ -static void coerce_it(void ** s) { *s = AO_gettext(*s); -} - -/** - * Translate all the translatable strings in the genshelloptOptions - * structure defined above. This is done only once. - */ -static void -translate_option_strings(void) -{ - tOptions * const opts = &genshelloptOptions; - - /* - * Guard against re-translation. It won't work. The strings will have - * been changed by the first pass through this code. One shot only. - */ - if (option_xlateable_txt.field_ct != 0) { - /* - * Do the translations. The first pointer follows the field count - * field. The field count field is the size of a pointer. - */ - char ** ppz = (char**)VOIDP(&(option_xlateable_txt)); - int ix = option_xlateable_txt.field_ct; - - do { - ppz++; /* skip over field_ct */ - *ppz = AO_gettext(*ppz); - } while (--ix > 0); - /* prevent re-translation and disable "libopts" domain lookup */ - option_xlateable_txt.field_ct = 0; - - coerce_it(VOIDP(&(opts->pzCopyright))); - coerce_it(VOIDP(&(opts->pzCopyNotice))); - coerce_it(VOIDP(&(opts->pzFullVersion))); - coerce_it(VOIDP(&(opts->pzUsageTitle))); - coerce_it(VOIDP(&(opts->pzExplain))); - coerce_it(VOIDP(&(opts->pzDetail))); - { - tOptDesc * od = opts->pOptDesc; - for (ix = opts->optCt; ix > 0; ix--, od++) - coerce_it(VOIDP(&(od->pzText))); - } - } -} -#endif /* ENABLE_NLS */ - -#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT -/** I18N function strictly for xgettext. Do not compile. */ -static void bogus_function(void) { - /* TRANSLATORS: - - The following dummy function was crated solely so that xgettext can - extract the correct strings. These strings are actually referenced - by a field name in the genshelloptOptions structure noted in the - comments below. The literal text is defined in genshellopt_opt_strs. - - NOTE: the strings below are segmented with respect to the source string - genshellopt_opt_strs. The strings above are handed off for translation - at run time a paragraph at a time. Consequently, they are presented here - for translation a paragraph at a time. - - ALSO: often the description for an option will reference another option - by name. These are set off with apostrophe quotes (I hope). Do not - translate option names. - */ - /* referenced via genshelloptOptions.pzCopyright */ - puts(_("genshellopt 1\n\ -Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n\ -This is free software. It is licensed for use, modification and\n\ -redistribution under the terms of the GNU Lesser General Public License,\n\ -version 2 or later \n")); - - /* referenced via genshelloptOptions.pzCopyNotice */ - puts(_("The genshellopt library is free software; you can redistribute it and/or\n\ -modify it under the terms of the GNU Library General Public License as\n\ -published by the Free Software Foundation; either version 2 of the License,\n\ -or (at your option) any later version.\n\n")); - puts(_("This library is distributed in the hope that it will be useful, but WITHOUT\n\ -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\ -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n\ -License for more details.\n\n")); - puts(_("You should have received a copy of the GNU Library General Public License\n\ -along with this library; if not, see\n\ -\n")); - - /* referenced via genshelloptOptions.pOptDesc->pzText */ - puts(_("Output Script File")); - - /* referenced via genshelloptOptions.pOptDesc->pzText */ - puts(_("Shell name (follows \"#!\" magic)")); - - /* referenced via genshelloptOptions.pOptDesc->pzText */ - puts(_("display extended usage information and exit")); - - /* referenced via genshelloptOptions.pOptDesc->pzText */ - puts(_("extended usage information passed thru pager")); - - /* referenced via genshelloptOptions.pOptDesc->pzText */ - puts(_("output version information and exit")); - - /* referenced via genshelloptOptions.pzUsageTitle */ - puts(_("genshellopt - Generate Shell Option Processing Script - Ver. 1\n\ -Usage: %s [ - [] | --[{=| }] ]...\n")); - - /* referenced via genshelloptOptions.pzExplain */ - puts(_("Note that 'shell' is only useful if the output file does not already exist.\n\ -If it does, then the shell name and optional first argument will be\n\ -extracted from the script file.\n")); - - /* referenced via genshelloptOptions.pzDetail */ - puts(_("If the script file already exists and contains Automated Option Processing\n\ -text, the second line of the file through the ending tag will be replaced\n\ -by the newly generated text. The first '#!' line will be regenerated.\n")); - - /* referenced via genshelloptOptions.pzFullVersion */ - puts(_("genshellopt 1")); - - /* referenced via genshelloptOptions.pzFullUsage */ - puts(_("<<>>")); - - /* referenced via genshelloptOptions.pzShortUsage */ - puts(_("<<>>")); - /* LIBOPTS-MESSAGES: */ -#line 67 "../autoopts.c" - puts(_("allocation of %d bytes failed\n")); -#line 89 "../autoopts.c" - puts(_("allocation of %d bytes failed\n")); -#line 48 "../init.c" - puts(_("AutoOpts function called without option descriptor\n")); -#line 81 "../init.c" - puts(_("\tThis exceeds the compiled library version: ")); -#line 79 "../init.c" - puts(_("Automated Options Processing Error!\n" - "\t%s called AutoOpts function with structure version %d:%d:%d.\n")); -#line 78 "../autoopts.c" - puts(_("realloc of %d bytes at 0x%p failed\n")); -#line 83 "../init.c" - puts(_("\tThis is less than the minimum library version: ")); -#line 121 "../version.c" - puts(_("Automated Options version %s\n" - "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n")); -#line 49 "../makeshell.c" - puts(_("(AutoOpts bug): %s.\n")); -#line 90 "../reset.c" - puts(_("optionResetOpt() called, but reset-option not configured")); -#line 241 "../usage.c" - puts(_("could not locate the 'help' option")); -#line 330 "../autoopts.c" - puts(_("optionProcess() was called with invalid data")); -#line 697 "../usage.c" - puts(_("invalid argument type specified")); -#line 568 "../find.c" - puts(_("defaulted to option with optional arg")); -#line 76 "../alias.c" - puts(_("aliasing option is out of range.")); -#line 210 "../enum.c" - puts(_("%s error: the keyword '%s' is ambiguous for %s\n")); -#line 78 "../find.c" - puts(_(" The following options match:\n")); -#line 263 "../find.c" - puts(_("%s: ambiguous option name: %s (matches %d options)\n")); -#line 161 "../check.c" - puts(_("%s: Command line arguments required\n")); -#line 43 "../alias.c" - puts(_("%d %s%s options allowed\n")); -#line 56 "../makeshell.c" - puts(_("%s error %d (%s) calling %s for '%s'\n")); -#line 268 "../makeshell.c" - puts(_("interprocess pipe")); -#line 171 "../version.c" - puts(_("error: version option argument '%c' invalid. Use:\n" - "\t'v' - version only\n" - "\t'c' - version and copyright\n" - "\t'n' - version and full copyright notice\n")); -#line 58 "../check.c" - puts(_("%s error: the '%s' and '%s' options conflict\n")); -#line 187 "../find.c" - puts(_("%s: The '%s' option has been disabled.")); -#line 400 "../find.c" - puts(_("%s: The '%s' option has been disabled.")); -#line 38 "../alias.c" - puts(_("-equivalence")); -#line 439 "../find.c" - puts(_("%s: illegal option -- %c\n")); -#line 110 "../reset.c" - puts(_("%s: illegal option -- %c\n")); -#line 241 "../find.c" - puts(_("%s: illegal option -- %s\n")); -#line 740 "../find.c" - puts(_("%s: illegal option -- %s\n")); -#line 118 "../reset.c" - puts(_("%s: illegal option -- %s\n")); -#line 305 "../find.c" - puts(_("%s: unknown vendor extension option -- %s\n")); -#line 135 "../enum.c" - puts(_(" or an integer from %d through %d\n")); -#line 145 "../enum.c" - puts(_(" or an integer from %d through %d\n")); -#line 696 "../usage.c" - puts(_("%s error: invalid option descriptor for %s\n")); -#line 1030 "../usage.c" - puts(_("%s error: invalid option descriptor for %s\n")); -#line 355 "../find.c" - puts(_("%s: invalid option name: %s\n")); -#line 497 "../find.c" - puts(_("%s: The '%s' option requires an argument.\n")); -#line 150 "../autoopts.c" - puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" - "\t'%s' and '%s'.")); -#line 94 "../check.c" - puts(_("%s error: The %s option is required\n")); -#line 602 "../find.c" - puts(_("%s: The '%s' option cannot have an argument.\n")); -#line 151 "../check.c" - puts(_("%s: Command line arguments are not allowed.\n")); -#line 568 "../save.c" - puts(_("error %d (%s) creating %s\n")); -#line 210 "../enum.c" - puts(_("%s error: '%s' does not match any %s keywords.\n")); -#line 93 "../reset.c" - puts(_("%s error: The '%s' option requires an argument.\n")); -#line 122 "../save.c" - puts(_("error %d (%s) stat-ing %s\n")); -#line 175 "../save.c" - puts(_("error %d (%s) stat-ing %s\n")); -#line 143 "../restore.c" - puts(_("%s error: no saved option state\n")); -#line 225 "../autoopts.c" - puts(_("'%s' is not a command line option.\n")); -#line 113 "../time.c" - puts(_("%s error: '%s' is not a recognizable date/time.\n")); -#line 50 "../time.c" - puts(_("%s error: '%s' is not a recognizable time duration.\n")); -#line 92 "../check.c" - puts(_("%s error: The %s option must appear %d times.\n")); -#line 165 "../numeric.c" - puts(_("%s error: '%s' is not a recognizable number.\n")); -#line 176 "../enum.c" - puts(_("%s error: %s exceeds %s keyword count\n")); -#line 279 "../usage.c" - puts(_("Try '%s %s' for more information.\n")); -#line 45 "../alias.c" - puts(_("one %s%s option allowed\n")); -#line 170 "../makeshell.c" - puts(_("standard output")); -#line 905 "../makeshell.c" - puts(_("standard output")); -#line 223 "../usage.c" - puts(_("standard output")); -#line 364 "../usage.c" - puts(_("standard output")); -#line 574 "../usage.c" - puts(_("standard output")); -#line 178 "../version.c" - puts(_("standard output")); -#line 223 "../usage.c" - puts(_("standard error")); -#line 364 "../usage.c" - puts(_("standard error")); -#line 574 "../usage.c" - puts(_("standard error")); -#line 178 "../version.c" - puts(_("standard error")); -#line 170 "../makeshell.c" - puts(_("write")); -#line 905 "../makeshell.c" - puts(_("write")); -#line 222 "../usage.c" - puts(_("write")); -#line 363 "../usage.c" - puts(_("write")); -#line 573 "../usage.c" - puts(_("write")); -#line 177 "../version.c" - puts(_("write")); -#line 60 "../numeric.c" - puts(_("%s error: %s option value %ld is out of range.\n")); -#line 44 "../check.c" - puts(_("%s error: %s option requires the %s option\n")); -#line 121 "../save.c" - puts(_("%s warning: cannot save options - %s not regular file\n")); -#line 174 "../save.c" - puts(_("%s warning: cannot save options - %s not regular file\n")); -#line 193 "../save.c" - puts(_("%s warning: cannot save options - %s not regular file\n")); -#line 567 "../save.c" - puts(_("%s warning: cannot save options - %s not regular file\n")); - /* END-LIBOPTS-MESSAGES */ - - /* USAGE-TEXT: */ -#line 822 "../usage.c" - puts(_("\t\t\t\t- an alternate for '%s'\n")); -#line 1097 "../usage.c" - puts(_("Version, usage and configuration options:")); -#line 873 "../usage.c" - puts(_("\t\t\t\t- default option for unnamed options\n")); -#line 786 "../usage.c" - puts(_("\t\t\t\t- disabled as '--%s'\n")); -#line 1066 "../usage.c" - puts(_(" --- %-14s %s\n")); -#line 1064 "../usage.c" - puts(_("This option has been disabled")); -#line 813 "../usage.c" - puts(_("\t\t\t\t- enabled by default\n")); -#line 40 "../alias.c" - puts(_("%s error: only ")); -#line 1143 "../usage.c" - puts(_(" - examining environment variables named %s_*\n")); -#line 168 "../file.c" - puts(_("\t\t\t\t- file must not pre-exist\n")); -#line 172 "../file.c" - puts(_("\t\t\t\t- file must pre-exist\n")); -#line 329 "../usage.c" - puts(_("Options are specified by doubled hyphens and their name or by a single\n" - "hyphen and the flag character.\n")); -#line 882 "../makeshell.c" - puts(_("\n" - "= = = = = = = =\n\n" - "This incarnation of genshell will produce\n" - "a shell script to parse the options for %s:\n\n")); -#line 142 "../enum.c" - puts(_(" or an integer mask with any of the lower %d bits set\n")); -#line 846 "../usage.c" - puts(_("\t\t\t\t- is a set membership option\n")); -#line 867 "../usage.c" - puts(_("\t\t\t\t- must appear between %d and %d times\n")); -#line 331 "../usage.c" - puts(_("Options are specified by single or double hyphens and their name.\n")); -#line 853 "../usage.c" - puts(_("\t\t\t\t- may appear multiple times\n")); -#line 840 "../usage.c" - puts(_("\t\t\t\t- may not be preset\n")); -#line 1258 "../usage.c" - puts(_(" Arg Option-Name Description\n")); -#line 1194 "../usage.c" - puts(_(" Flg Arg Option-Name Description\n")); -#line 1252 "../usage.c" - puts(_(" Flg Arg Option-Name Description\n")); -#line 1253 "../usage.c" - puts(_(" %3s %s")); -#line 1259 "../usage.c" - puts(_(" %3s %s")); -#line 336 "../usage.c" - puts(_("The '-#' option may omit the hash char\n")); -#line 332 "../usage.c" - puts(_("All arguments are named options.\n")); -#line 920 "../usage.c" - puts(_(" - reading file %s")); -#line 358 "../usage.c" - puts(_("\n" - "Please send bug reports to: <%s>\n")); -#line 100 "../version.c" - puts(_("\n" - "Please send bug reports to: <%s>\n")); -#line 129 "../version.c" - puts(_("\n" - "Please send bug reports to: <%s>\n")); -#line 852 "../usage.c" - puts(_("\t\t\t\t- may NOT appear - preset only\n")); -#line 893 "../usage.c" - puts(_("\n" - "The following option preset mechanisms are supported:\n")); -#line 1141 "../usage.c" - puts(_("\n" - "The following option preset mechanisms are supported:\n")); -#line 631 "../usage.c" - puts(_("prohibits these options:\n")); -#line 626 "../usage.c" - puts(_("prohibits the option '%s'\n")); -#line 81 "../numeric.c" - puts(_("%s%ld to %ld")); -#line 79 "../numeric.c" - puts(_("%sgreater than or equal to %ld")); -#line 75 "../numeric.c" - puts(_("%s%ld exactly")); -#line 68 "../numeric.c" - puts(_("%sit must lie in one of the ranges:\n")); -#line 68 "../numeric.c" - puts(_("%sit must be in the range:\n")); -#line 88 "../numeric.c" - puts(_(", or\n")); -#line 66 "../numeric.c" - puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n")); -#line 77 "../numeric.c" - puts(_("%sless than or equal to %ld")); -#line 339 "../usage.c" - puts(_("Operands and options may be intermixed. They will be reordered.\n")); -#line 601 "../usage.c" - puts(_("requires the option '%s'\n")); -#line 604 "../usage.c" - puts(_("requires these options:\n")); -#line 1270 "../usage.c" - puts(_(" Arg Option-Name Req? Description\n")); -#line 1264 "../usage.c" - puts(_(" Flg Arg Option-Name Req? Description\n")); -#line 143 "../enum.c" - puts(_("or you may use a numeric representation. Preceding these with a '!'\n" - "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" - "will set them all. Multiple entries may be passed as an option\n" - "argument list.\n")); -#line 859 "../usage.c" - puts(_("\t\t\t\t- may appear up to %d times\n")); -#line 52 "../enum.c" - puts(_("The valid \"%s\" option keywords are:\n")); -#line 1101 "../usage.c" - puts(_("The next option supports vendor supported extra options:")); -#line 722 "../usage.c" - puts(_("These additional options are:")); - /* END-USAGE-TEXT */ -} -#endif /* uncompilable code */ -#ifdef __cplusplus -} -#endif -/* genshell.c ends here */ diff --git a/src/libopts/genshell.h b/src/libopts/genshell.h deleted file mode 100644 index 994af16..0000000 --- a/src/libopts/genshell.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (genshell.h) - * - * It has been AutoGen-ed - * From the definitions genshell.def - * and the template file options - * - * Generated from AutoOpts 42:1:17 templates. - * - * AutoOpts is a copyrighted work. This header file is not encumbered - * by AutoOpts licensing, but is provided under the licensing terms chosen - * by the genshellopt author or copyright holder. AutoOpts is - * licensed under the terms of the LGPL. The redistributable library - * (``libopts'') is licensed under the terms of either the LGPL or, at the - * users discretion, the BSD license. See the AutoOpts and/or libopts sources - * for details. - * - * The genshellopt program is copyrighted and licensed - * under the following terms: - * - * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. - * This is free software. It is licensed for use, modification and - * redistribution under the terms of the GNU Lesser General Public License, - * version 2 or later - * - * The genshellopt library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see - * - */ -/** - * This file contains the programmatic interface to the Automated - * Options generated for the genshellopt program. - * These macros are documented in the AutoGen info file in the - * "AutoOpts" chapter. Please refer to that doc for usage help. - */ -#ifndef AUTOOPTS_GENSHELL_H_GUARD -#define AUTOOPTS_GENSHELL_H_GUARD 1 -#include -#include -#include - -/** - * Ensure that the library used for compiling this generated header is at - * least as new as the version current when the header template was released - * (not counting patch version increments). Also ensure that the oldest - * tolerable version is at least as old as what was current when the header - * template was released. - */ -#define AO_TEMPLATE_VERSION 172033 -#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ - || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) -# error option template version mismatches autoopts/options.h header - Choke Me. -#endif - -#if GCC_VERSION > 40400 -#define NOT_REACHED __builtin_unreachable(); -#else -#define NOT_REACHED -#endif - -/** - * Enumeration of each option type for genshellopt - */ -typedef enum { - INDEX_GENSHELL_OPT_SCRIPT = 0, - INDEX_GENSHELL_OPT_SHELL = 1, - INDEX_GENSHELL_OPT_VERSION = 2, - INDEX_GENSHELL_OPT_HELP = 3, - INDEX_GENSHELL_OPT_MORE_HELP = 4 -} teGenshell_OptIndex; -/** count of all options for genshellopt */ -#define GENSHELL_OPTION_CT 5 -/** genshellopt version */ -#define GENSHELLOPT_VERSION "1" -/** Full genshellopt version text */ -#define GENSHELLOPT_FULL_VERSION "genshellopt 1" - -/** - * Interface defines for all options. Replace "n" with the UPPER_CASED - * option name (as in the teGenshell_OptIndex enumeration above). - * e.g. HAVE_GENSHELL_OPT(SCRIPT) - */ -#define GENSHELL_DESC(n) (genshelloptOptions.pOptDesc[INDEX_GENSHELL_OPT_## n]) -/** 'true' if an option has been specified in any way */ -#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n))) -/** The string argument to an option. The argument type must be \"string\". */ -#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString) -/** Mask the option state revealing how an option was specified. - * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, - * \a OPTST_DEFINED, \a OPTST_RESET or zero. - */ -#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK) -/** Count of option's occurrances *on the command line*. */ -#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt) -/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ -#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n))) -/** 'true' if \a HAVE_OPT would yield 'false'. */ -#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n))) -/** 'true' if OPTST_DISABLED bit not set. */ -#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n))) -/** number of stacked option arguments. - * Valid only for stacked option arguments. */ -#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt) -/** stacked argument vector. - * Valid only for stacked option arguments. */ -#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs) -/** Reset an option. */ -#define CLEAR_GENSHELL_OPT(n) STMTS( \ - GENSHELL_DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ - if ((GENSHELL_DESC(n).fOptState & OPTST_INITENABLED) == 0) \ - GENSHELL_DESC(n).fOptState |= OPTST_DISABLED; \ - GENSHELL_DESC(n).optCookie = NULL ) -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** - * Enumeration of genshellopt exit codes - */ -typedef enum { - GENSHELLOPT_EXIT_SUCCESS = 0, - GENSHELLOPT_EXIT_FAILURE = 1, - GENSHELLOPT_EXIT_USAGE_ERROR = 64, - GENSHELLOPT_EXIT_LIBOPTS_FAILURE = 70 -} genshellopt_exit_code_t; -/** - * Interface defines for specific options. - * @{ - */ -#define VALUE_GENSHELL_OPT_SCRIPT 'o' -#define VALUE_GENSHELL_OPT_SHELL 's' -/** option flag (value) for help-value option */ -#define VALUE_GENSHELL_OPT_HELP '?' -/** option flag (value) for more-help-value option */ -#define VALUE_GENSHELL_OPT_MORE_HELP '!' -/** option flag (value) for version-value option */ -#define VALUE_GENSHELL_OPT_VERSION 'v' -/* - * Interface defines not associated with particular options - */ -#define ERRSKIP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP) -#define ERRSTOP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP) -#define RESTART_GENSHELL_OPT(n) STMTS( \ - genshelloptOptions.curOptIdx = (n); \ - genshelloptOptions.pzCurOpt = NULL ) -#define START_GENSHELL_OPT RESTART_GENSHELL_OPT(1) -#define GENSHELL_USAGE(c) (*genshelloptOptions.pUsageProc)(&genshelloptOptions, c) - -#ifdef __cplusplus -extern "C" { -#endif -/* - * global exported definitions - */ -#define ch_t unsigned char -#define cc_t const unsigned char -#define cch_t char const - - -/* * * * * * - * - * Declare the genshellopt option descriptor. - */ -extern tOptions genshelloptOptions; - -#if defined(ENABLE_NLS) -# ifndef _ -# include -# ifndef HAVE_GETTEXT - extern char * gettext(char const *); -# else -# include -# endif - -# ifndef ATTRIBUTE_FORMAT_ARG -# define ATTRIBUTE_FORMAT_ARG(_a) -# endif - -static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1); -static inline char* aoGetsText(char const* pz) { - if (pz == NULL) return NULL; - return (char*)gettext(pz); -} -# define _(s) aoGetsText(s) -# endif /* _() */ - -# define OPT_NO_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet |= \ - OPTPROC_NXLAT_OPT_CFG;) -# define OPT_NO_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet |= \ - OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) - -# define OPT_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet &= \ - ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) -# define OPT_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet &= \ - ~OPTPROC_NXLAT_OPT;) - -#else /* ENABLE_NLS */ -# define OPT_NO_XLAT_CFG_NAMES -# define OPT_NO_XLAT_OPT_NAMES - -# define OPT_XLAT_CFG_NAMES -# define OPT_XLAT_OPT_NAMES - -# ifndef _ -# define _(_s) _s -# endif -#endif /* ENABLE_NLS */ - - -#ifdef __cplusplus -} -#endif -#endif /* AUTOOPTS_GENSHELL_H_GUARD */ - -/* genshell.h ends here */ diff --git a/src/libopts/gettext.h b/src/libopts/gettext.h deleted file mode 100644 index 87ec819..0000000 --- a/src/libopts/gettext.h +++ /dev/null @@ -1,294 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2018 Free Software - Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License along - with this program; if not, see . */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option - or through "#define ENABLE NLS 0" before including this file. */ -#if defined ENABLE_NLS && ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# undef gettext -# define gettext(Msgid) ((const char *) (Msgid)) -# undef dgettext -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# undef dcgettext -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# undef dngettext -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# undef dcngettext -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) -# undef textdomain -# define textdomain(Domainname) ((const char *) (Domainname)) -# undef bindtextdomain -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# undef bind_textdomain_codeset -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* Prefer gnulib's setlocale override over libintl's setlocale override. */ -#ifdef GNULIB_defined_setlocale -# undef setlocale -# define setlocale rpl_setlocale -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ - /* || __STDC_VERSION__ == 199901L - || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ) -# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 -#else -# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 -#endif - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - int found_translation; - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); - found_translation = (translation != msg_ctxt_id); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (found_translation) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - int found_translation; - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (found_translation) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/src/libopts/init.c b/src/libopts/init.c deleted file mode 100644 index b65e593..0000000 --- a/src/libopts/init.c +++ /dev/null @@ -1,289 +0,0 @@ -/** - * \file initialize.c - * - * initialize the libopts data structures. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * Make sure the option descriptor is there and that we understand it. - * This should be called from any user entry point where one needs to - * worry about validity. (Some entry points are free to assume that - * the call is not the first to the library and, thus, that this has - * already been called.) - * - * Upon successful completion, pzProgName and pzProgPath are set. - * - * @param[in,out] opts program options descriptor - * @param[in] pname name of program, from argv[] - * @returns SUCCESS or FAILURE - */ -static tSuccess -validate_struct(tOptions * opts, char const * pname) -{ - if (opts == NULL) { - fputs(zno_opt_arg, stderr); - return FAILURE; - } - print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0); - - /* - * IF the client has enabled translation and the translation procedure - * is available, then go do it. - */ - if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) - && (opts->pTransProc != NULL) - && (option_xlateable_txt.field_ct != 0) ) { - /* - * If option names are not to be translated at all, then do not do - * it for configuration parsing either. (That is the bit that really - * gets tested anyway.) - */ - if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT) - opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG; - opts->pTransProc(); - } - - /* - * IF the struct version is not the current, and also - * either too large (?!) or too small, - * THEN emit error message and fail-exit - */ - if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION ) - && ( (opts->structVersion > OPTIONS_STRUCT_VERSION ) - || (opts->structVersion < OPTIONS_MINIMUM_VERSION ) - ) ) { - fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion)); - if (opts->structVersion > OPTIONS_STRUCT_VERSION ) - fputs(ztoo_new, stderr); - else - fputs(ztoo_old, stderr); - - fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr); - return FAILURE; - } - - /* - * If the program name hasn't been set, then set the name and the path - * and the set of equivalent characters. - */ - if (opts->pzProgName == NULL) { - char const * pz = strrchr(pname, DIRCH); - char const ** pp = - (char const **)(void **)&(opts->pzProgName); - - if (pz != NULL) - *pp = pz+1; - else - *pp = pname; - - pz = pathfind(getenv("PATH"), (char *)pname, "rx"); - if (pz != NULL) - pname = VOIDP(pz); - - pp = (char const **)VOIDP(&(opts->pzProgPath)); - *pp = pname; - - /* - * when comparing long names, these are equivalent - */ - strequate(zSepChars); - } - - return SUCCESS; -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * DO PRESETS - * - * The next several routines do the immediate action pass on the command - * line options, then the environment variables, then the config files in - * reverse order. Once done with that, the order is reversed and all - * the config files and environment variables are processed again, this - * time only processing the non-immediate action options. do_presets() - * will then return for optionProcess() to do the final pass on the command - * line arguments. - */ - -/** - * scan the command line for immediate action options. - * This is only called the first time through. - * While this procedure is active, the OPTPROC_IMMEDIATE is true. - * - * @param pOpts program options descriptor - * @returns SUCCESS or FAILURE - */ -static tSuccess -immediate_opts(tOptions * opts) -{ - tSuccess res; - - opts->fOptSet |= OPTPROC_IMMEDIATE; - opts->curOptIdx = 1; /* start by skipping program name */ - opts->pzCurOpt = NULL; - - /* - * Examine all the options from the start. We process any options that - * are marked for immediate processing. - */ - for (;;) { - tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); - - res = next_opt(opts, &opt_st); - switch (res) { - case FAILURE: goto failed_option; - case PROBLEM: res = SUCCESS; goto leave; - case SUCCESS: break; - } - - /* - * IF this is an immediate-attribute option, then do it. - */ - if (! DO_IMMEDIATELY(opt_st.flags)) - continue; - - if (! SUCCESSFUL(handle_opt(opts, &opt_st))) - break; - } failed_option:; - - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - (*opts->pUsageProc)(opts, EXIT_FAILURE); - - leave: - - opts->fOptSet &= ~OPTPROC_IMMEDIATE; - return res; -} - -/** - * check for preset values from a config files or envrionment variables - * - * @param[in,out] opts the structure with the option names to check - */ -static tSuccess -do_presets(tOptions * opts) -{ - tOptDesc * od = NULL; - - if (! SUCCESSFUL(immediate_opts(opts))) - return FAILURE; - - /* - * IF this option set has a --save-opts option, then it also - * has a --load-opts option. See if a command line option has disabled - * option presetting. - */ - if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT) - && (opts->specOptIdx.save_opts != 0)) { - od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; - if (DISABLED_OPT(od)) - return SUCCESS; - } - - /* - * Until we return from this procedure, disable non-presettable opts - */ - opts->fOptSet |= OPTPROC_PRESETTING; - /* - * IF there are no config files, - * THEN do any environment presets and leave. - */ - if (opts->papzHomeList == NULL) { - env_presets(opts, ENV_ALL); - } - else { - env_presets(opts, ENV_IMM); - - /* - * Check to see if environment variables have disabled presetting. - */ - if ((od != NULL) && ! DISABLED_OPT(od)) - intern_file_load(opts); - - /* - * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment - * variable options. Only the loading of .rc files. - */ - env_presets(opts, ENV_NON_IMM); - } - opts->fOptSet &= ~OPTPROC_PRESETTING; - - return SUCCESS; -} - -/** - * AutoOpts initialization - * - * @param[in,out] opts the structure to initialize - * @param[in] a_ct program argument count - * @param[in] a_v program argument vector - */ -static bool -ao_initialize(tOptions * opts, int a_ct, char ** a_v) -{ - if ((opts->fOptSet & OPTPROC_INITDONE) != 0) - return true; - - opts->origArgCt = (unsigned int)a_ct; - opts->origArgVect = a_v; - opts->fOptSet |= OPTPROC_INITDONE; - - if (HAS_pzPkgDataDir(opts)) - program_pkgdatadir = opts->pzPkgDataDir; - - if (! SUCCESSFUL(do_presets(opts))) - return false; - - /* - * IF option name conversion was suppressed but it is not suppressed - * for the command line, then it's time to translate option names. - * Usage text will not get retranslated. - */ - if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) - && (opts->pTransProc != NULL) - && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) - ) { - opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; - (*opts->pTransProc)(); - } - - if ((opts->fOptSet & OPTPROC_REORDER) != 0) - optionSort(opts); - - opts->curOptIdx = 1; - opts->pzCurOpt = NULL; - return true; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/initialize.c */ diff --git a/src/libopts/intprops.h b/src/libopts/intprops.h deleted file mode 100644 index af456ff..0000000 --- a/src/libopts/intprops.h +++ /dev/null @@ -1,453 +0,0 @@ -/* intprops.h -- properties of integer types - - Copyright (C) 2001-2018 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . */ - -/* Written by Paul Eggert. */ - -#ifndef _GL_INTPROPS_H -#define _GL_INTPROPS_H - -#include - -/* Return a value with the common real type of E and V and the value of V. */ -#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) - -/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see - . */ -#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) - -/* The extra casts in the following macros work around compiler bugs, - e.g., in Cray C 5.0.3.0. */ - -/* True if the arithmetic type T is an integer type. bool counts as - an integer. */ -#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) - -/* True if the real type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* Return 1 if the real expression E, after promotion, has a - signed or floating type. */ -#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) - - -/* Minimum and maximum values for integer types and expressions. */ - -/* The width in bits of the integer type or expression T. - Padding bits are not supported; this is checked at compile-time below. */ -#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) - -/* The maximum and minimum values for the integer type T. */ -#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) -#define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) - -/* The maximum and minimum values for the type of the expression E, - after integer promotion. E should not have side effects. */ -#define _GL_INT_MINIMUM(e) \ - (EXPR_SIGNED (e) \ - ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_CONVERT (e, 0)) -#define _GL_INT_MAXIMUM(e) \ - (EXPR_SIGNED (e) \ - ? _GL_SIGNED_INT_MAXIMUM (e) \ - : _GL_INT_NEGATE_CONVERT (e, 1)) -#define _GL_SIGNED_INT_MAXIMUM(e) \ - (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1) - -/* Work around OpenVMS incompatibility with C99. */ -#if !defined LLONG_MAX && defined __INT64_MAX -# define LLONG_MAX __INT64_MAX -# define LLONG_MIN __INT64_MIN -#endif - -/* This include file assumes that signed types are two's complement without - padding bits; the above macros have undefined behavior otherwise. - If this is a problem for you, please let us know how to fix it for your host. - This assumption is tested by the intprops-tests module. */ - -/* Does the __typeof__ keyword work? This could be done by - 'configure', but for now it's easier to do it by hand. */ -#if (2 <= __GNUC__ \ - || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ - || (0x5110 <= __SUNPRO_C && !__STDC__)) -# define _GL_HAVE___TYPEOF__ 1 -#else -# define _GL_HAVE___TYPEOF__ 0 -#endif - -/* Return 1 if the integer type or expression T might be signed. Return 0 - if it is definitely unsigned. This macro does not evaluate its argument, - and expands to an integer constant expression. */ -#if _GL_HAVE___TYPEOF__ -# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) -#else -# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 -#endif - -/* Bound on length of the string representing an unsigned integer - value representable in B bits. log10 (2.0) < 146/485. The - smallest value of B where this bound is not tight is 2621. */ -#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) - -/* Bound on length of the string representing an integer type or expression T. - Subtract 1 for the sign bit if T is signed, and then add 1 more for - a minus sign if needed. - - Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is - signed, this macro may overestimate the true bound by one byte when - applied to unsigned types of size 2, 4, 16, ... bytes. */ -#define INT_STRLEN_BOUND(t) \ - (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \ - + _GL_SIGNED_TYPE_OR_EXPR (t)) - -/* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ -#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) - - -/* Range overflow checks. - - The INT__RANGE_OVERFLOW macros return 1 if the corresponding C - operators might not yield numerically correct answers due to - arithmetic overflow. They do not rely on undefined or - implementation-defined behavior. Their implementations are simple - and straightforward, but they are a bit harder to use than the - INT__OVERFLOW macros described below. - - Example usage: - - long int i = ...; - long int j = ...; - if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) - printf ("multiply would overflow"); - else - printf ("product is %ld", i * j); - - Restrictions on *_RANGE_OVERFLOW macros: - - These macros do not check for all possible numerical problems or - undefined or unspecified behavior: they do not check for division - by zero, for bad shift counts, or for shifting negative numbers. - - These macros may evaluate their arguments zero or multiple times, - so the arguments should not have side effects. The arithmetic - arguments (including the MIN and MAX arguments) must be of the same - integer type after the usual arithmetic conversions, and the type - must have minimum value MIN and maximum MAX. Unsigned types should - use a zero MIN of the proper type. - - These macros are tuned for constant MIN and MAX. For commutative - operations such as A + B, they are also tuned for constant B. */ - -/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? (a) < (min) - (b) \ - : (max) - (b) < (a)) - -/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? (max) + (b) < (a) \ - : (a) < (min) + (b)) - -/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. - See above for restrictions. */ -#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ - ((min) < 0 \ - ? (a) < - (max) \ - : 0 < (a)) - -/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Avoid && and || as they tickle - bugs in Sun C 5.11 2010/08/13 and other compilers; see - . */ -#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ - ((b) < 0 \ - ? ((a) < 0 \ - ? (a) < (max) / (b) \ - : (b) == -1 \ - ? 0 \ - : (min) / (b) < (a)) \ - : (b) == 0 \ - ? 0 \ - : ((a) < 0 \ - ? (a) < (min) / (b) \ - : (max) / (b) < (a))) - -/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Do not check for division by zero. */ -#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ - ((min) < 0 && (b) == -1 && (a) < - (max)) - -/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Do not check for division by zero. - Mathematically, % should never overflow, but on x86-like hosts - INT_MIN % -1 traps, and the C standard permits this, so treat this - as an overflow too. */ -#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ - INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) - -/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. - See above for restrictions. Here, MIN and MAX are for A only, and B need - not be of the same type as the other arguments. The C standard says that - behavior is undefined for shifts unless 0 <= B < wordwidth, and that when - A is negative then A << B has undefined behavior and A >> B has - implementation-defined behavior, but do not check these other - restrictions. */ -#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ - ((a) < 0 \ - ? (a) < (min) >> (b) \ - : (max) >> (b) < (a)) - -/* True if __builtin_add_overflow (A, B, P) works when P is non-null. */ -#if 5 <= __GNUC__ && !defined __ICC -# define _GL_HAS_BUILTIN_OVERFLOW 1 -#else -# define _GL_HAS_BUILTIN_OVERFLOW 0 -#endif - -/* True if __builtin_add_overflow_p (A, B, C) works. */ -#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) - -/* The _GL*_OVERFLOW macros have the same restrictions as the - *_RANGE_OVERFLOW macros, except that they do not assume that operands - (e.g., A and B) have the same type as MIN and MAX. Instead, they assume - that the result (e.g., A + B) has that type. */ -#if _GL_HAS_BUILTIN_OVERFLOW_P -# define _GL_ADD_OVERFLOW(a, b, min, max) \ - __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) -# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ - __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0) -# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ - __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0) -#else -# define _GL_ADD_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? (b) <= (a) + (b) \ - : (b) < 0 ? (a) <= (a) + (b) \ - : (a) + (b) < (b)) -# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ - : (a) < 0 ? 1 \ - : (b) < 0 ? (a) - (b) <= (a) \ - : (a) < (b)) -# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ - (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ - || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) -#endif -#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ - : (a) < 0 ? (b) <= (a) + (b) - 1 \ - : (b) < 0 && (a) + (b) <= (a)) -#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ - ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ - : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ - : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) - -/* Return a nonzero value if A is a mathematical multiple of B, where - A is unsigned, B is negative, and MAX is the maximum value of A's - type. A's type must be the same as (A % B)'s type. Normally (A % - -B == 0) suffices, but things get tricky if -B would overflow. */ -#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ - (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ - ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ - ? (a) \ - : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ - : (a) % - (b)) \ - == 0) - -/* Check for integer overflow, and report low order bits of answer. - - The INT__OVERFLOW macros return 1 if the corresponding C operators - might not yield numerically correct answers due to arithmetic overflow. - The INT__WRAPV macros also store the low-order bits of the answer. - These macros work correctly on all known practical hosts, and do not rely - on undefined behavior due to signed arithmetic overflow. - - Example usage, assuming A and B are long int: - - if (INT_MULTIPLY_OVERFLOW (a, b)) - printf ("result would overflow\n"); - else - printf ("result is %ld (no overflow)\n", a * b); - - Example usage with WRAPV flavor: - - long int result; - bool overflow = INT_MULTIPLY_WRAPV (a, b, &result); - printf ("result is %ld (%s)\n", result, - overflow ? "after overflow" : "no overflow"); - - Restrictions on these macros: - - These macros do not check for all possible numerical problems or - undefined or unspecified behavior: they do not check for division - by zero, for bad shift counts, or for shifting negative numbers. - - These macros may evaluate their arguments zero or multiple times, so the - arguments should not have side effects. - - The WRAPV macros are not constant expressions. They support only - +, binary -, and *. The result type must be signed. - - These macros are tuned for their last argument being a constant. - - Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, - A % B, and A << B would overflow, respectively. */ - -#define INT_ADD_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) -#define INT_SUBTRACT_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) -#if _GL_HAS_BUILTIN_OVERFLOW_P -# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a) -#else -# define INT_NEGATE_OVERFLOW(a) \ - INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) -#endif -#define INT_MULTIPLY_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) -#define INT_DIVIDE_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) -#define INT_REMAINDER_OVERFLOW(a, b) \ - _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) -#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ - INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ - _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) - -/* Return 1 if the expression A B would overflow, - where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, - assuming MIN and MAX are the minimum and maximum for the result type. - Arguments should be free of side effects. */ -#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ - op_result_overflow (a, b, \ - _GL_INT_MINIMUM (0 * (b) + (a)), \ - _GL_INT_MAXIMUM (0 * (b) + (a))) - -/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. - Return 1 if the result overflows. See above for restrictions. */ -#define INT_ADD_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW) -#define INT_SUBTRACT_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW) -#define INT_MULTIPLY_WRAPV(a, b, r) \ - _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW) - -/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 - https://llvm.org/bugs/show_bug.cgi?id=25390 - For now, assume all versions of GCC-like compilers generate bogus - warnings for _Generic. This matters only for older compilers that - lack __builtin_add_overflow. */ -#if __GNUC__ -# define _GL__GENERIC_BOGUS 1 -#else -# define _GL__GENERIC_BOGUS 0 -#endif - -/* Store the low-order bits of A B into *R, where OP specifies - the operation. BUILTIN is the builtin operation, and OVERFLOW the - overflow predicate. Return 1 if the result overflows. See above - for restrictions. */ -#if _GL_HAS_BUILTIN_OVERFLOW -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r) -#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ - (_Generic \ - (*(r), \ - signed char: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - signed char, SCHAR_MIN, SCHAR_MAX), \ - short int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - short int, SHRT_MIN, SHRT_MAX), \ - int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - int, INT_MIN, INT_MAX), \ - long int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ - long int, LONG_MIN, LONG_MAX), \ - long long int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ - long long int, LLONG_MIN, LLONG_MAX))) -#else -# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ - (sizeof *(r) == sizeof (signed char) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - signed char, SCHAR_MIN, SCHAR_MAX) \ - : sizeof *(r) == sizeof (short int) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - short int, SHRT_MIN, SHRT_MAX) \ - : sizeof *(r) == sizeof (int) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ - int, INT_MIN, INT_MAX) \ - : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow)) -# ifdef LLONG_MAX -# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ - (sizeof *(r) == sizeof (long int) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ - long int, LONG_MIN, LONG_MAX) \ - : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ - long long int, LLONG_MIN, LLONG_MAX)) -# else -# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ - long int, LONG_MIN, LONG_MAX) -# endif -#endif - -/* Store the low-order bits of A B into *R, where the operation - is given by OP. Use the unsigned type UT for calculation to avoid - overflow problems. *R's type is T, with extrema TMIN and TMAX. - T must be a signed integer type. Return 1 if the result overflows. */ -#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ - (sizeof ((a) op (b)) < sizeof (t) \ - ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \ - : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax)) -#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \ - ((overflow (a, b) \ - || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \ - || (tmax) < ((a) op (b))) \ - ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ - : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) - -/* Return the low-order bits of A B, where the operation is given - by OP. Use the unsigned type UT for calculation to avoid undefined - behavior on signed integer overflow, and convert the result to type T. - UT is at least as wide as T and is no narrower than unsigned int, - T is two's complement, and there is no padding or trap representations. - Assume that converting UT to T yields the low-order bits, as is - done in all known two's-complement C compilers. E.g., see: - https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html - - According to the C standard, converting UT to T yields an - implementation-defined result or signal for values outside T's - range. However, code that works around this theoretical problem - runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: - https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html - As the compiler bug is real, don't try to work around the - theoretical problem. */ - -#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ - ((t) ((ut) (a) op (ut) (b))) - -#endif /* _GL_INTPROPS_H */ diff --git a/src/libopts/libopts.c b/src/libopts/libopts.c deleted file mode 100644 index 457edc4..0000000 --- a/src/libopts/libopts.c +++ /dev/null @@ -1,50 +0,0 @@ -#define AUTOOPTS_INTERNAL 1 -#include "autoopts/project.h" - -#include "ao-strs.h" -static char const ao_ver_string[] = - "42:1:17\n"; -#include "autoopts/options.h" -#include "autoopts/usage-txt.h" -#include "genshell.h" -#include "option-xat-attribute.h" -#include "option-value-type.h" -#include "ao-strs.h" -#include "ag-char-map.h" -#include "save-flags.h" -#include "autoopts.h" -#include "proto.h" -#include "parse-duration.c" -#include "ao-strs.c" -#include "option-value-type.c" -#include "option-xat-attribute.c" -#include "save-flags.c" -#include "autoopts.c" -#include "alias.c" -#include "boolean.c" -#include "check.c" -#include "configfile.c" -#include "cook.c" -#include "enum.c" -#include "env.c" -#include "file.c" -#include "find.c" -#include "genshell.c" -#include "load.c" -#include "makeshell.c" -#include "nested.c" -#include "numeric.c" -#include "pgusage.c" -#include "putshell.c" -#include "reset.c" -#include "restore.c" -#include "save.c" -#include "sort.c" -#include "stack.c" -#include "streqvcmp.c" -#include "text_mmap.c" -#include "time.c" -#include "tokenize.c" -#include "usage.c" -#include "version.c" -#include "init.c" diff --git a/src/libopts/load.c b/src/libopts/load.c deleted file mode 100644 index 59d124e..0000000 --- a/src/libopts/load.c +++ /dev/null @@ -1,578 +0,0 @@ - -/** - * \file load.c - * - * This file contains the routines that deal with processing text strings - * for options, either from a NUL-terminated string passed in or from an - * rc/ini file. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -static bool -get_realpath(char * buf, size_t b_sz) -{ -#if defined(HAVE_CANONICALIZE_FILE_NAME) - { - size_t name_len; - - char * pz = canonicalize_file_name(buf); - if (pz == NULL) - return false; - - name_len = strlen(pz); - if (name_len >= (size_t)b_sz) { - free(pz); - return false; - } - - memcpy(buf, pz, name_len + 1); - free(pz); - } - -#elif defined(HAVE_REALPATH) - { - size_t name_len; - char z[PATH_MAX+1]; - - if (realpath(buf, z) == NULL) - return false; - - name_len = strlen(z); - if (name_len >= b_sz) - return false; - - memcpy(buf, z, name_len + 1); - } -#endif - return true; -} - -/*=export_func optionMakePath - * private: - * - * what: translate and construct a path - * arg: + char * + p_buf + The result buffer + - * arg: + int + b_sz + The size of this buffer + - * arg: + char const * + fname + The input name + - * arg: + char const * + prg_path + The full path of the current program + - * - * ret-type: bool - * ret-desc: true if the name was handled, otherwise false. - * If the name does not start with ``$'', then it is handled - * simply by copying the input name to the output buffer and - * resolving the name with either - * @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}. - * - * doc: - * - * This routine will copy the @code{pzName} input name into the - * @code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the - * first character of the input name is a @code{'$'} character, then there - * is special handling: - * @* - * @code{$$} is replaced with the directory name of the @code{pzProgPath}, - * searching @code{$PATH} if necessary. - * @* - * @code{$@} is replaced with the AutoGen package data installation directory - * (aka @code{pkgdatadir}). - * @* - * @code{$NAME} is replaced by the contents of the @code{NAME} environment - * variable. If not found, the search fails. - * - * Please note: both @code{$$} and @code{$NAME} must be at the start of the - * @code{pzName} string and must either be the entire string or be followed - * by the @code{'/'} (backslash on windows) character. - * - * err: @code{false} is returned if: - * @* - * @bullet{} The input name exceeds @code{bufSize} bytes. - * @* - * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string - * and the next character is not '/'. - * @* - * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@} - * was specified. - * @* - * @bullet{} @code{NAME} is not a known environment variable - * @* - * @bullet{} @code{canonicalize_file_name} or @code{realpath} return - * errors (cannot resolve the resulting path). -=*/ -bool -optionMakePath(char * p_buf, int b_sz, char const * fname, char const * prg_path) -{ - { - size_t len = strlen(fname); - - if (((size_t)b_sz <= len) || (len == 0)) - return false; - } - - /* - * IF not an environment variable, just copy the data - */ - if (*fname != '$') { - char const * src = fname; - char * dst = p_buf; - int ct = b_sz; - - for (;;) { - if ( (*(dst++) = *(src++)) == NUL) - break; - if (--ct <= 0) - return false; - } - } - - /* - * IF the name starts with "$$", then it must be "$$" or - * it must start with "$$/". In either event, replace the "$$" - * with the path to the executable and append a "/" character. - */ - else switch (fname[1]) { - case NUL: - return false; - - case '$': - if (! add_prog_path(p_buf, b_sz, fname, prg_path)) - return false; - break; - - case '@': - if (program_pkgdatadir[0] == NUL) - return false; - - if (snprintf(p_buf, (size_t)b_sz, "%s%s", - program_pkgdatadir, fname + 2) >= b_sz) - return false; - break; - - default: - if (! add_env_val(p_buf, b_sz, fname)) - return false; - } - - return get_realpath(p_buf, b_sz); -} - -/** - * convert a leading "$$" into a path to the executable. - */ -static bool -add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path) -{ - char const * path; - char const * pz; - int skip = 2; - size_t fname_len; - size_t dir_len; //!< length of the directory portion of the path to the exe - - switch (fname[2]) { - case DIRCH: - skip = 3; - case NUL: - break; - default: - return false; - } - - /* - * See if the path is included in the program name. - * If it is, we're done. Otherwise, we have to hunt - * for the program using "pathfind". - */ - if (strchr(prg_path, DIRCH) != NULL) - path = prg_path; - else { - path = pathfind(getenv("PATH"), (char *)prg_path, "rx"); - - if (path == NULL) - return false; - } - - pz = strrchr(path, DIRCH); - - /* - * IF we cannot find a directory name separator, - * THEN we do not have a path name to our executable file. - */ - if (pz == NULL) - return false; - - fname += skip; - fname_len = strlen(fname) + 1; // + NUL byte - dir_len = (pz - path) + 1; // + dir sep character - - /* - * Concatenate the file name to the end of the executable path. - * The result may be either a file or a directory. - */ - if (dir_len + fname_len > (unsigned)b_sz) - return false; - - memcpy(buf, path, dir_len); - memcpy(buf + dir_len, fname, fname_len); - - /* - * If the "path" path was gotten from "pathfind()", then it was - * allocated and we need to deallocate it. - */ - if (path != prg_path) - AGFREE(path); - return true; -} - -/** - * Add an environment variable value. - */ -static bool -add_env_val(char * buf, int buf_sz, char const * name) -{ - char * dir_part = buf; - - for (;;) { - int ch = (int)*++name; - if (! IS_VALUE_NAME_CHAR(ch)) - break; - *(dir_part++) = (char)ch; - } - - if (dir_part == buf) - return false; - - *dir_part = NUL; - - dir_part = getenv(buf); - - /* - * Environment value not found -- skip the home list entry - */ - if (dir_part == NULL) - return false; - - { - size_t dir_len = strlen(dir_part); - size_t nm_len = strlen(name) + 1; - - if (dir_len + nm_len >= (unsigned)buf_sz) - return false; - memcpy(buf, dir_part, dir_len); - memcpy(buf + dir_len, name, nm_len); - } - - return true; -} - -/** - * Trim leading and trailing white space. - * If we are cooking the text and the text is quoted, then "cook" - * the string. To cook, the string must be quoted. - * - * @param[in,out] txt the input and output string - * @param[in] mode the handling mode (cooking method) - */ -static void -munge_str(char * txt, tOptionLoadMode mode) -{ - char * end; - - if (mode == OPTION_LOAD_KEEP) - return; - - if (IS_WHITESPACE_CHAR(*txt)) { - char * src = SPN_WHITESPACE_CHARS(txt+1); - size_t l = strlen(src) + 1; - memmove(txt, src, l); - end = txt + l - 1; - - } else - end = txt + strlen(txt); - - end = SPN_WHITESPACE_BACK(txt, end); - *end = NUL; - - if (mode == OPTION_LOAD_UNCOOKED) - return; - - switch (*txt) { - default: return; - case '"': - case '\'': break; - } - - switch (end[-1]) { - default: return; - case '"': - case '\'': break; - } - - (void)ao_string_cook(txt, NULL); -} - -static char * -assemble_arg_val(char * txt, tOptionLoadMode mode) -{ - char * end = strpbrk(txt, ARG_BREAK_STR); - int space_break; - - /* - * Not having an argument to a configurable name is okay. - */ - if (end == NULL) - return txt + strlen(txt); - - /* - * If we are keeping all whitespace, then the modevalue starts with the - * character that follows the end of the configurable name, regardless - * of which character caused it. - */ - if (mode == OPTION_LOAD_KEEP) { - *(end++) = NUL; - return end; - } - - /* - * If the name ended on a white space character, remember that - * because we'll have to skip over an immediately following ':' or '=' - * (and the white space following *that*). - */ - space_break = IS_WHITESPACE_CHAR(*end); - *(end++) = NUL; - - end = SPN_WHITESPACE_CHARS(end); - if (space_break && ((*end == ':') || (*end == '='))) - end = SPN_WHITESPACE_CHARS(end+1); - - return end; -} - -static char * -trim_quotes(char * arg) -{ - switch (*arg) { - case '"': - case '\'': - ao_string_cook(arg, NULL); - } - return arg; -} - -/** - * See if the option is to be processed in the current scan direction - * (-1 or +1). - */ -static bool -direction_ok(opt_state_mask_t f, int dir) -{ - if (dir == 0) - return true; - - switch (f & (OPTST_IMM|OPTST_DISABLE_IMM)) { - case 0: - /* - * The selected option has no immediate action. - * THEREFORE, if the direction is PRESETTING - * THEN we skip this option. - */ - if (PRESETTING(dir)) - return false; - break; - - case OPTST_IMM: - if (PRESETTING(dir)) { - /* - * We are in the presetting direction with an option we handle - * immediately for enablement, but normally for disablement. - * Therefore, skip if disabled. - */ - if ((f & OPTST_DISABLED) == 0) - return false; - } else { - /* - * We are in the processing direction with an option we handle - * immediately for enablement, but normally for disablement. - * Therefore, skip if NOT disabled. - */ - if ((f & OPTST_DISABLED) != 0) - return false; - } - break; - - case OPTST_DISABLE_IMM: - if (PRESETTING(dir)) { - /* - * We are in the presetting direction with an option we handle - * immediately for disablement, but normally for handling. - * Therefore, skip if NOT disabled. - */ - if ((f & OPTST_DISABLED) != 0) - return false; - } else { - /* - * We are in the processing direction with an option we handle - * immediately for disablement, but normally for handling. - * Therefore, skip if disabled. - */ - if ((f & OPTST_DISABLED) == 0) - return false; - } - break; - - case OPTST_IMM|OPTST_DISABLE_IMM: - /* - * The selected option is always for immediate action. - * THEREFORE, if the direction is PROCESSING - * THEN we skip this option. - */ - if (PROCESSING(dir)) - return false; - break; - } - return true; -} - -/** - * Load an option from a block of text. The text must start with the - * configurable/option name and be followed by its associated value. - * That value may be processed in any of several ways. See "tOptionLoadMode" - * in autoopts.h. - * - * @param[in,out] opts program options descriptor - * @param[in,out] opt_state option processing state - * @param[in,out] line source line with long option name in it - * @param[in] direction current processing direction (preset or not) - * @param[in] load_mode option loading mode (OPTION_LOAD_*) - */ -static void -load_opt_line(tOptions * opts, tOptState * opt_state, char * line, - tDirection direction, tOptionLoadMode load_mode ) -{ - /* - * When parsing a stored line, we only look at the characters after - * a hyphen. Long names must always be at least two characters and - * short options are always exactly one character long. - */ - line = SPN_LOAD_LINE_SKIP_CHARS(line); - - { - char * arg = assemble_arg_val(line, load_mode); - - if (IS_OPTION_NAME_CHAR(line[1])) { - - if (! SUCCESSFUL(opt_find_long(opts, line, opt_state))) - return; - - } else if (! SUCCESSFUL(opt_find_short(opts, *line, opt_state))) - return; - - if ((! CALLED(direction)) && (opt_state->flags & OPTST_NO_INIT)) - return; - - opt_state->pzOptArg = trim_quotes(arg); - } - - if (! direction_ok(opt_state->flags, direction)) - return; - - /* - * Fix up the args. - */ - if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) { - if (*opt_state->pzOptArg != NUL) - return; - opt_state->pzOptArg = NULL; - - } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) { - if (*opt_state->pzOptArg == NUL) - opt_state->pzOptArg = NULL; - else { - AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); - opt_state->flags |= OPTST_ALLOC_ARG; - } - - } else { - if (*opt_state->pzOptArg == NUL) - opt_state->pzOptArg = zNil; - else { - AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); - opt_state->flags |= OPTST_ALLOC_ARG; - } - } - - { - tOptionLoadMode sv = option_load_mode; - option_load_mode = load_mode; - handle_opt(opts, opt_state); - option_load_mode = sv; - } -} - -/*=export_func optionLoadLine - * - * what: process a string for an option name and value - * - * arg: tOptions *, opts, program options descriptor - * arg: char const *, line, NUL-terminated text - * - * doc: - * - * This is a client program callable routine for setting options from, for - * example, the contents of a file that they read in. Only one option may - * appear in the text. It will be treated as a normal (non-preset) option. - * - * When passed a pointer to the option struct and a string, it will find - * the option named by the first token on the string and set the option - * argument to the remainder of the string. The caller must NUL terminate - * the string. The caller need not skip over any introductory hyphens. - * Any embedded new lines will be included in the option - * argument. If the input looks like one or more quoted strings, then the - * input will be "cooked". The "cooking" is identical to the string - * formation used in AutoGen definition files (@pxref{basic expression}), - * except that you may not use backquotes. - * - * err: Invalid options are silently ignored. Invalid option arguments - * will cause a warning to print, but the function should return. -=*/ -void -optionLoadLine(tOptions * opts, char const * line) -{ - tOptState st = OPTSTATE_INITIALIZER(SET); - char * pz; - proc_state_mask_t sv_flags = opts->fOptSet; - opts->fOptSet &= ~OPTPROC_ERRSTOP; - AGDUPSTR(pz, line, "opt line"); - load_opt_line(opts, &st, pz, DIRECTION_CALLED, OPTION_LOAD_COOKED); - AGFREE(pz); - opts->fOptSet = sv_flags; -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/load.c */ diff --git a/src/libopts/makeshell.c b/src/libopts/makeshell.c deleted file mode 100644 index 10ed120..0000000 --- a/src/libopts/makeshell.c +++ /dev/null @@ -1,918 +0,0 @@ - -/** - * \file makeshell.c - * - * This module will interpret the options set in the tOptions - * structure and create a Bourne shell script capable of parsing them. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - - static inline unsigned char to_uchar (char ch) { return ch; } - -#define UPPER(_c) (toupper(to_uchar(_c))) -#define LOWER(_c) (tolower(to_uchar(_c))) - -noreturn static void -option_exits(int exit_code) -{ - if (print_exit) - printf("\nexit %d\n", exit_code); - exit(exit_code); -} - -noreturn static void -ao_bug(char const * msg) -{ - fprintf(stderr, zao_bug_msg, msg); - option_exits(EX_SOFTWARE); -} - -static void -fserr_warn(char const * prog, char const * op, char const * fname) -{ - fprintf(stderr, zfserr_fmt, prog, errno, strerror(errno), - op, fname); -} - -noreturn static void -fserr_exit(char const * prog, char const * op, char const * fname) -{ - fserr_warn(prog, op, fname); - option_exits(EXIT_FAILURE); -} - -/*=export_func optionParseShell - * private: - * - * what: Decipher a boolean value - * arg: + tOptions * + pOpts + program options descriptor + - * - * doc: - * Emit a shell script that will parse the command line options. -=*/ -void -optionParseShell(tOptions * opts) -{ - /* - * Check for our SHELL option now. - * IF the output file contains the "#!" magic marker, - * it will override anything we do here. - */ - if (HAVE_GENSHELL_OPT(SHELL)) - shell_prog = GENSHELL_OPT_ARG(SHELL); - - else if (! ENABLED_GENSHELL_OPT(SHELL)) - shell_prog = NULL; - - else if ((shell_prog = getenv("SHELL")), - shell_prog == NULL) - - shell_prog = POSIX_SHELL; - - /* - * Check for a specified output file - */ - if (HAVE_GENSHELL_OPT(SCRIPT)) - open_out(GENSHELL_OPT_ARG(SCRIPT), opts->pzProgName); - - emit_usage(opts); - emit_setup(opts); - - /* - * There are four modes of option processing. - */ - switch (opts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) { - case OPTPROC_LONGOPT: - fputs(LOOP_STR, stdout); - - fputs(LONG_OPT_MARK, stdout); - fputs(INIT_LOPT_STR, stdout); - emit_long(opts); - printf(LOPT_ARG_FMT, opts->pzPROGNAME); - fputs(END_OPT_SEL_STR, stdout); - - fputs(NOT_FOUND_STR, stdout); - break; - - case 0: - fputs(ONLY_OPTS_LOOP, stdout); - fputs(INIT_LOPT_STR, stdout); - emit_long(opts); - printf(LOPT_ARG_FMT, opts->pzPROGNAME); - break; - - case OPTPROC_SHORTOPT: - fputs(LOOP_STR, stdout); - - fputs(FLAG_OPT_MARK, stdout); - fputs(INIT_OPT_STR, stdout); - emit_flag(opts); - printf(OPT_ARG_FMT, opts->pzPROGNAME); - fputs(END_OPT_SEL_STR, stdout); - - fputs(NOT_FOUND_STR, stdout); - break; - - case OPTPROC_LONGOPT|OPTPROC_SHORTOPT: - fputs(LOOP_STR, stdout); - - fputs(LONG_OPT_MARK, stdout); - fputs(INIT_LOPT_STR, stdout); - emit_long(opts); - printf(LOPT_ARG_FMT, opts->pzPROGNAME); - fputs(END_OPT_SEL_STR, stdout); - - fputs(FLAG_OPT_MARK, stdout); - fputs(INIT_OPT_STR, stdout); - emit_flag(opts); - printf(OPT_ARG_FMT, opts->pzPROGNAME); - fputs(END_OPT_SEL_STR, stdout); - - fputs(NOT_FOUND_STR, stdout); - break; - } - - emit_wrapup(opts); - if ((script_trailer != NULL) && (*script_trailer != NUL)) - fputs(script_trailer, stdout); - else if (ENABLED_GENSHELL_OPT(SHELL)) - printf(SHOW_PROG_ENV, opts->pzPROGNAME); - -#ifdef HAVE_FCHMOD - fchmod(STDOUT_FILENO, 0755); -#endif - fclose(stdout); - - if (ferror(stdout)) - fserr_exit(opts->pzProgName, zwriting, zstdout_name); - - AGFREE(script_text); - script_leader = NULL; - script_trailer = NULL; - script_text = NULL; -} - -#ifdef HAVE_WORKING_FORK -/** - * Print the value of "var" to a file descriptor. - * The "fdin" is the read end of a pipe to a forked process that - * is writing usage text to it. We read that text in and re-emit - * to standard out, formatting it so that it is assigned to a - * shell variable. - * - * @param[in] prog The capitalized, c-variable-formatted program name - * @param[in] var a similarly formatted type name - * (LONGUSAGE, USAGE or VERSION) - * @param[in] fdin the input end of a pipe - */ -static void -emit_var_text(char const * prog, char const * var, int fdin) -{ - FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG); - int nlct = 0; /* defer newlines and skip trailing ones */ - - printf(SET_TEXT_FMT, prog, var); - if (fp == NULL) - goto skip_text; - - for (;;) { - int ch = fgetc(fp); - switch (ch) { - - case NL: - nlct++; - break; - - case '\'': - while (nlct > 0) { - fputc(NL, stdout); - nlct--; - } - fputs(apostrophe, stdout); - break; - - case EOF: - goto done; - - default: - while (nlct > 0) { - fputc(NL, stdout); - nlct--; - } - fputc(ch, stdout); - break; - } - } done:; - - fclose(fp); - - skip_text: - - fputs(END_SET_TEXT, stdout); -} -#endif - -/** - * The purpose of this function is to assign "long usage", short usage - * and version information to a shell variable. Rather than wind our - * way through all the logic necessary to emit the text directly, we - * fork(), have our child process emit the text the normal way and - * capture the output in the parent process. - * - * @param[in] opts the program options - * @param[in] which what to print: long usage, usage or version - * @param[in] od for TT_VERSION, it is the version option - */ -static void -text_to_var(tOptions * opts, teTextTo which, tOptDesc * od) -{ -# define _TT_(n) static char const z ## n [] = #n; - TEXTTO_TABLE -# undef _TT_ -# define _TT_(n) z ## n , - static char const * ttnames[] = { TEXTTO_TABLE }; -# undef _TT_ - -#if ! defined(HAVE_WORKING_FORK) - printf(SET_NO_TEXT_FMT, opts->pzPROGNAME, ttnames[which]); -#else - int fdpair[2]; - - fflush(stdout); - fflush(stderr); - - if (pipe(fdpair) != 0) - fserr_exit(opts->pzProgName, "pipe", zinter_proc_pipe); - - switch (fork()) { - case -1: - fserr_exit(opts->pzProgName, "fork", opts->pzProgName); - /* NOTREACHED */ - - case 0: - /* - * Send both stderr and stdout to the pipe. No matter which - * descriptor is used, we capture the output on the read end. - */ - dup2(fdpair[1], STDERR_FILENO); - dup2(fdpair[1], STDOUT_FILENO); - close(fdpair[0]); - - switch (which) { - case TT_LONGUSAGE: - (*(opts->pUsageProc))(opts, EXIT_SUCCESS); - /* FALLTHROUGH */ /* NOTREACHED */ - - case TT_USAGE: - (*(opts->pUsageProc))(opts, EXIT_FAILURE); - /* FALLTHROUGH */ /* NOTREACHED */ - - case TT_VERSION: - if (od->fOptState & OPTST_ALLOC_ARG) { - AGFREE(od->optArg.argString); - od->fOptState &= ~OPTST_ALLOC_ARG; - } - od->optArg.argString = "c"; - optionPrintVersion(opts, od); - /* FALLTHROUGH */ /* NOTREACHED */ - - default: - option_exits(EXIT_FAILURE); - /* FALLTHROUGH */ /* NOTREACHED */ - } - /* FALLTHROUGH */ /* NOTREACHED */ - - default: - close(fdpair[1]); - } - - emit_var_text(opts->pzPROGNAME, ttnames[which], fdpair[0]); -#endif -} - -/** - * capture usage text in shell variables. - * - */ -static void -emit_usage(tOptions * opts) -{ - char tm_nm_buf[AO_NAME_SIZE]; - - /* - * First, switch stdout to the output file name. - * Then, change the program name to the one defined - * by the definitions (rather than the current - * executable name). Down case the upper cased name. - */ - if (script_leader != NULL) - fputs(script_leader, stdout); - - { - char const * out_nm; - - { - time_t c_tim = time(NULL); - struct tm * ptm = localtime(&c_tim); - strftime(tm_nm_buf, AO_NAME_SIZE, TIME_FMT, ptm ); - } - - if (HAVE_GENSHELL_OPT(SCRIPT)) - out_nm = GENSHELL_OPT_ARG(SCRIPT); - else out_nm = STDOUT; - - if ((script_leader == NULL) && (shell_prog != NULL)) - printf(SHELL_MAGIC, shell_prog); - - printf(PREAMBLE_FMT, START_MARK, out_nm, tm_nm_buf); - } - - printf(END_PRE_FMT, opts->pzPROGNAME); - - /* - * Get a copy of the original program name in lower case and - * fill in an approximation of the program name from it. - */ - { - char * pzPN = tm_nm_buf; - char const * pz = opts->pzPROGNAME; - char ** pp; - - /* Copy the program name into the time/name buffer */ - for (;;) { - if ((*pzPN++ = (char)tolower(*pz++)) == NUL) - break; - } - - pp = VOIDP(&(opts->pzProgPath)); - *pp = tm_nm_buf; - pp = VOIDP(&(opts->pzProgName)); - *pp = tm_nm_buf; - } - - text_to_var(opts, TT_LONGUSAGE, NULL); - text_to_var(opts, TT_USAGE, NULL); - - { - tOptDesc * pOptDesc = opts->pOptDesc; - int optionCt = opts->optCt; - - for (;;) { - if (pOptDesc->pOptProc == optionPrintVersion) { - text_to_var(opts, TT_VERSION, pOptDesc); - break; - } - - if (--optionCt <= 0) - break; - pOptDesc++; - } - } -} - -static void -emit_wrapup(tOptions * opts) -{ - tOptDesc * od = opts->pOptDesc; - int opt_ct = opts->presetOptCt; - char const * fmt; - - printf(FINISH_LOOP, opts->pzPROGNAME); - for (;opt_ct > 0; od++, --opt_ct) { - /* - * Options that are either usage documentation or are compiled out - * are not to be processed. - */ - if (SKIP_OPT(od) || (od->pz_NAME == NULL)) - continue; - - /* - * do not presence check if there is no minimum/must-set - */ - if ((od->optMinCt == 0) && ((od->fOptState & OPTST_MUST_SET) == 0)) - continue; - - if (od->optMaxCt > 1) - fmt = CHK_MIN_COUNT; - else fmt = CHK_ONE_REQUIRED; - - { - int min = (od->optMinCt == 0) ? 1 : od->optMinCt; - printf(fmt, opts->pzPROGNAME, od->pz_NAME, min); - } - } - fputs(END_MARK, stdout); -} - -static void -emit_setup(tOptions * opts) -{ - tOptDesc * od = opts->pOptDesc; - int opt_ct = opts->presetOptCt; - char const * fmt; - char const * def_val; - - for (;opt_ct > 0; od++, --opt_ct) { - char int_val_buf[32]; - - /* - * Options that are either usage documentation or are compiled out - * are not to be processed. - */ - if (SKIP_OPT(od) || (od->pz_NAME == NULL)) - continue; - - if (od->optMaxCt > 1) - fmt = MULTI_DEF_FMT; - else fmt = SGL_DEF_FMT; - - /* - * IF this is an enumeration/bitmask option, then convert the value - * to a string before printing the default value. - */ - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_ENUMERATION: - (*(od->pOptProc))(OPTPROC_EMIT_SHELL, od ); - def_val = od->optArg.argString; - break; - - /* - * Numeric and membership bit options are just printed as a number. - */ - case OPARG_TYPE_NUMERIC: - snprintf(int_val_buf, sizeof(int_val_buf), "%d", - (int)od->optArg.argInt); - def_val = int_val_buf; - break; - - case OPARG_TYPE_MEMBERSHIP: - snprintf(int_val_buf, sizeof(int_val_buf), "%lu", - (unsigned long)od->optArg.argIntptr); - def_val = int_val_buf; - break; - - case OPARG_TYPE_BOOLEAN: - def_val = (od->optArg.argBool) ? TRUE_STR : FALSE_STR; - break; - - default: - if (od->optArg.argString == NULL) { - if (fmt == SGL_DEF_FMT) - fmt = SGL_NO_DEF_FMT; - def_val = NULL; - } - else - def_val = od->optArg.argString; - } - - printf(fmt, opts->pzPROGNAME, od->pz_NAME, def_val); - } -} - -static void -emit_action(tOptions * opts, tOptDesc * od) -{ - if (od->pOptProc == optionPrintVersion) - printf(ECHO_N_EXIT, opts->pzPROGNAME, VER_STR); - - else if (od->pOptProc == optionPagedUsage) - printf(PAGE_USAGE_TEXT, opts->pzPROGNAME); - - else if (od->pOptProc == optionLoadOpt) { - printf(LVL3_CMD, NO_LOAD_WARN); - printf(LVL3_CMD, YES_NEED_OPT_ARG); - - } else if (od->pz_NAME == NULL) { - - if (od->pOptProc == NULL) { - printf(LVL3_CMD, NO_SAVE_OPTS); - printf(LVL3_CMD, OK_NEED_OPT_ARG); - } else - printf(ECHO_N_EXIT, opts->pzPROGNAME, LONG_USE_STR); - - } else { - if (od->optMaxCt == 1) - printf(SGL_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); - else { - if ((unsigned)od->optMaxCt < NOLIMIT) - printf(CHK_MAX_COUNT, opts->pzPROGNAME, - od->pz_NAME, od->optMaxCt); - - printf(MULTI_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); - } - - /* - * Fix up the args. - */ - if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NONE) { - printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); - printf(LVL3_CMD, NO_ARG_NEEDED); - - } else if (od->fOptState & OPTST_ARG_OPTIONAL) { - printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); - printf(LVL3_CMD, OK_NEED_OPT_ARG); - - } else { - printf(LVL3_CMD, YES_NEED_OPT_ARG); - } - } - fputs(zOptionEndSelect, stdout); -} - -static void -emit_inaction(tOptions * opts, tOptDesc * od) -{ - if (od->pOptProc == optionLoadOpt) { - printf(LVL3_CMD, NO_SUPPRESS_LOAD); - - } else if (od->optMaxCt == 1) - printf(NO_SGL_ARG_FMT, opts->pzPROGNAME, - od->pz_NAME, od->pz_DisablePfx); - else - printf(NO_MULTI_ARG_FMT, opts->pzPROGNAME, - od->pz_NAME, od->pz_DisablePfx); - - printf(LVL3_CMD, NO_ARG_NEEDED); - fputs(zOptionEndSelect, stdout); -} - -/** - * recognize flag options. These go at the end. - * At the end, emit code to handle options we don't recognize. - * - * @param[in] opts the program options - */ -static void -emit_flag(tOptions * opts) -{ - tOptDesc * od = opts->pOptDesc; - int opt_ct = opts->optCt; - - fputs(zOptionCase, stdout); - - for (;opt_ct > 0; od++, --opt_ct) { - - if (SKIP_OPT(od) || ! IS_GRAPHIC_CHAR(od->optValue)) - continue; - - printf(zOptionFlag, od->optValue); - emit_action(opts, od); - } - printf(UNK_OPT_FMT, FLAG_STR, opts->pzPROGNAME); -} - -/** - * Emit the match text for a long option. The passed in \a name may be - * either the enablement name or the disablement name. - * - * @param[in] name The current name to check. - * @param[in] cod current option descriptor - * @param[in] opts the program options - */ -static void -emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts) -{ - char name_bf[32]; - unsigned int min_match_ct = 2; - unsigned int max_match_ct = strlen(name) - 1; - - if (max_match_ct >= sizeof(name_bf) - 1) - goto leave; - - { - tOptDesc * od = opts->pOptDesc; - int ct = opts->optCt; - - for (; ct-- > 0; od++) { - unsigned int match_ct = 0; - - /* - * Omit the current option, Doc opts and compiled out opts. - */ - if ((od == cod) || SKIP_OPT(od)) - continue; - - /* - * Check each character of the name case insensitively. - * They must not be the same. They cannot be, because it would - * not compile correctly if they were. - */ - while (UPPER(od->pz_Name[match_ct]) == UPPER(name[match_ct])) - match_ct++; - - if (match_ct > min_match_ct) - min_match_ct = match_ct; - - /* - * Check the disablement name, too. - */ - if (od->pz_DisableName == NULL) - continue; - - match_ct = 0; - while ( toupper(od->pz_DisableName[match_ct]) - == toupper(name[match_ct])) - match_ct++; - if (match_ct > min_match_ct) - min_match_ct = match_ct; - } - } - - /* - * Don't bother emitting partial matches if there is only one possible - * partial match. - */ - if (min_match_ct < max_match_ct) { - char * pz = name_bf + min_match_ct; - int nm_ix = min_match_ct; - - memcpy(name_bf, name, min_match_ct); - - for (;;) { - *pz = NUL; - printf(zOptionPartName, name_bf); - *pz++ = name[nm_ix++]; - if (name[nm_ix] == NUL) { - *pz = NUL; - break; - } - } - } - -leave: - printf(zOptionFullName, name); -} - -/** - * Emit GNU-standard long option handling code. - * - * @param[in] opts the program options - */ -static void -emit_long(tOptions * opts) -{ - tOptDesc * od = opts->pOptDesc; - int ct = opts->optCt; - - fputs(zOptionCase, stdout); - - /* - * do each option, ... - */ - do { - /* - * Documentation & compiled-out options - */ - if (SKIP_OPT(od)) - continue; - - emit_match_expr(od->pz_Name, od, opts); - emit_action(opts, od); - - /* - * Now, do the same thing for the disablement version of the option. - */ - if (od->pz_DisableName != NULL) { - emit_match_expr(od->pz_DisableName, od, opts); - emit_inaction(opts, od); - } - } while (od++, --ct > 0); - - printf(UNK_OPT_FMT, OPTION_STR, opts->pzPROGNAME); -} - -/** - * Load the previous shell script output file. We need to preserve any - * hand-edited additions outside of the START_MARK and END_MARKs. - * - * @param[in] fname the output file name - */ -static char * -load_old_output(char const * fname, char const * pname) -{ - /* - * IF we cannot stat the file, - * THEN assume we are creating a new file. - * Skip the loading of the old data. - */ - FILE * fp = fopen(fname, "r" FOPEN_BINARY_FLAG); - struct stat stbf; - char * text; - char * scan; - - if (fp == NULL) - return NULL; - - /* - * If we opened it, we should be able to stat it and it needs - * to be a regular file - */ - if ((fstat(fileno(fp), &stbf) != 0) || (! S_ISREG(stbf.st_mode))) - fserr_exit(pname, "fstat", fname); - - scan = text = AGALOC(stbf.st_size + 1, "f data"); - - /* - * Read in all the data as fast as our OS will let us. - */ - for (;;) { - size_t inct = fread(VOIDP(scan), 1, (size_t)stbf.st_size, fp); - if (inct == 0) - break; - - stbf.st_size -= (ssize_t)inct; - - if (stbf.st_size == 0) - break; - - scan += inct; - } - - *scan = NUL; - fclose(fp); - - return text; -} - -/** - * Open the specified output file. If it already exists, load its - * contents and save the non-generated (hand edited) portions. - * If a "start mark" is found, everything before it is preserved leader. - * If not, the entire thing is a trailer. Assuming the start is found, - * then everything after the end marker is the trailer. If the end - * mark is not found, the file is actually corrupt, but we take the - * remainder to be the trailer. - * - * @param[in] fname the output file name - */ -static void -open_out(char const * fname, char const * pname) -{ - - do { - char * txt = script_text = load_old_output(fname, pname); - char * scn; - - if (txt == NULL) - break; - - scn = strstr(txt, START_MARK); - if (scn == NULL) { - script_trailer = txt; - break; - } - - *(scn++) = NUL; - scn = strstr(scn, END_MARK); - if (scn == NULL) { - /* - * The file is corrupt. Set the trailer to be everything - * after the start mark. The user will need to fix it up. - */ - script_trailer = txt + strlen(txt) + START_MARK_LEN + 1; - break; - } - - /* - * Check to see if the data contains our marker. - * If it does, then we will skip over it - */ - script_trailer = scn + END_MARK_LEN; - script_leader = txt; - } while (false); - - if (freopen(fname, "w" FOPEN_BINARY_FLAG, stdout) != stdout) - fserr_exit(pname, "freopen", fname); -} - -/*=export_func genshelloptUsage - * private: - * what: The usage function for the genshellopt generated program - * - * arg: + tOptions * + opts + program options descriptor + - * arg: + int + exit_cd + usage text type to produce + - * - * doc: - * This function is used to create the usage strings for the option - * processing shell script code. Two child processes are spawned - * each emitting the usage text in either the short (error exit) - * style or the long style. The generated program will capture this - * and create shell script variables containing the two types of text. -=*/ -void -genshelloptUsage(tOptions * opts, int exit_cd) -{ -#if ! defined(HAVE_WORKING_FORK) - optionUsage(opts, exit_cd); -#else - /* - * IF not EXIT_SUCCESS, - * THEN emit the short form of usage. - */ - if (exit_cd != EXIT_SUCCESS) - optionUsage(opts, exit_cd); - fflush(stderr); - fflush(stdout); - if (ferror(stdout) || ferror(stderr)) - option_exits(EXIT_FAILURE); - - option_usage_fp = stdout; - - /* - * First, print our usage - */ - switch (fork()) { - case -1: - optionUsage(opts, EXIT_FAILURE); - /* FALLTHROUGH */ /* NOTREACHED */ - - case 0: - pagerState = PAGER_STATE_CHILD; - optionUsage(opts, EXIT_SUCCESS); - /* FALLTHROUGH */ /* NOTREACHED */ - - default: - { - int sts; - wait(&sts); - } - } - - /* - * Generate the pzProgName, since optionProcess() normally - * gets it from the command line - */ - { - char * pz; - char ** pp = VOIDP(&(optionParseShellOptions->pzProgName)); - AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name"); - *pp = pz; - while (*pz != NUL) { - *pz = (char)LOWER(*pz); - pz++; - } - } - - /* - * Separate the makeshell usage from the client usage - */ - fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName); - fflush(option_usage_fp); - - /* - * Now, print the client usage. - */ - switch (fork()) { - case 0: - pagerState = PAGER_STATE_CHILD; - /*FALLTHROUGH*/ - case -1: - optionUsage(optionParseShellOptions, EXIT_FAILURE); - /* FALLTHROUGH */ /* NOTREACHED */ - - default: - { - int sts; - wait(&sts); - } - } - - fflush(stdout); - if (ferror(stdout)) - fserr_exit(opts->pzProgName, zwriting, zstdout_name); - - option_exits(EXIT_SUCCESS); -#endif -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/makeshell.c */ diff --git a/src/libopts/nested.c b/src/libopts/nested.c deleted file mode 100644 index e760450..0000000 --- a/src/libopts/nested.c +++ /dev/null @@ -1,905 +0,0 @@ - -/** - * \file nested.c - * - * Handle options with arguments that contain nested values. - * - * @addtogroup autoopts - * @{ - */ -/* - * Automated Options Nested Values module. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -typedef struct { - int xml_ch; - int xml_len; - char xml_txt[8]; -} xml_xlate_t; - - static xml_xlate_t const xml_xlate[] = { - { '&', 4, "amp;" }, - { '<', 3, "lt;" }, - { '>', 3, "gt;" }, - { '"', 5, "quot;" }, - { '\'',5, "apos;" } -}; - -#ifndef ENOMSG -#define ENOMSG ENOENT -#endif - -/** - * Backslashes are used for line continuations. We keep the newline - * characters, but trim out the backslash: - */ -static void -remove_continuation(char * src) -{ - char * pzD; - - do { - while (*src == NL) src++; - pzD = strchr(src, NL); - if (pzD == NULL) - return; - - /* - * pzD has skipped at least one non-newline character and now - * points to a newline character. It now becomes the source and - * pzD goes to the previous character. - */ - src = pzD--; - if (*pzD != '\\') - pzD++; - } while (pzD == src); - - /* - * Start shifting text. - */ - for (;;) { - char ch = ((*pzD++) = *(src++)); - switch (ch) { - case NUL: return; - case '\\': - if (*src == NL) - --pzD; /* rewrite on next iteration */ - } - } -} - -/** - * Find the end of a quoted string, skipping escaped quote characters. - */ -static char const * -scan_q_str(char const * pzTxt) -{ - char q = *(pzTxt++); /* remember the type of quote */ - - for (;;) { - char ch = *(pzTxt++); - if (ch == NUL) - return pzTxt-1; - - if (ch == q) - return pzTxt; - - if (ch == '\\') { - ch = *(pzTxt++); - /* - * IF the next character is NUL, drop the backslash, too. - */ - if (ch == NUL) - return pzTxt - 2; - - /* - * IF the quote character or the escape character were escaped, - * then skip both, as long as the string does not end. - */ - if ((ch == q) || (ch == '\\')) { - if (*(pzTxt++) == NUL) - return pzTxt-1; - } - } - } -} - - -/** - * Associate a name with either a string or no value. - * - * @param[in,out] pp argument list to add to - * @param[in] name the name of the "suboption" - * @param[in] nm_len the length of the name - * @param[in] val the string value for the suboption - * @param[in] d_len the length of the value - * - * @returns the new value structure - */ -static tOptionValue * -add_string(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len) -{ - tOptionValue * pNV; - size_t sz = nm_len + d_len + sizeof(*pNV); - - pNV = AGALOC(sz, "option name/str value pair"); - - if (val == NULL) { - pNV->valType = OPARG_TYPE_NONE; - pNV->pzName = pNV->v.strVal; - - } else { - pNV->valType = OPARG_TYPE_STRING; - if (d_len > 0) { - char const * src = val; - char * pzDst = pNV->v.strVal; - int ct = (int)d_len; - do { - int ch = *(src++) & 0xFF; - if (ch == NUL) goto data_copy_done; - if (ch == '&') - ch = get_special_char(&src, &ct); - *(pzDst++) = (char)ch; - } while (--ct > 0); - data_copy_done: - *pzDst = NUL; - - } else { - pNV->v.strVal[0] = NUL; - } - - pNV->pzName = pNV->v.strVal + d_len + 1; - } - - memcpy(pNV->pzName, name, nm_len); - pNV->pzName[ nm_len ] = NUL; - addArgListEntry(pp, pNV); - return pNV; -} - -/** - * Associate a name with a boolean value - * - * @param[in,out] pp argument list to add to - * @param[in] name the name of the "suboption" - * @param[in] nm_len the length of the name - * @param[in] val the boolean value for the suboption - * @param[in] d_len the length of the value - * - * @returns the new value structure - */ -static tOptionValue * -add_bool(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len) -{ - size_t sz = nm_len + sizeof(tOptionValue) + 1; - tOptionValue * new_val = AGALOC(sz, "bool val"); - - /* - * Scan over whitespace is constrained by "d_len" - */ - while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { - d_len--; val++; - } - - if (d_len == 0) - new_val->v.boolVal = 0; - - else if (IS_DEC_DIGIT_CHAR(*val)) - new_val->v.boolVal = (unsigned)atoi(val); - - else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val); - - new_val->valType = OPARG_TYPE_BOOLEAN; - new_val->pzName = (char *)(new_val + 1); - memcpy(new_val->pzName, name, nm_len); - new_val->pzName[ nm_len ] = NUL; - addArgListEntry(pp, new_val); - return new_val; -} - -/** - * Associate a name with strtol() value, defaulting to zero. - * - * @param[in,out] pp argument list to add to - * @param[in] name the name of the "suboption" - * @param[in] nm_len the length of the name - * @param[in] val the numeric value for the suboption - * @param[in] d_len the length of the value - * - * @returns the new value structure - */ -static tOptionValue * -add_number(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len) -{ - size_t sz = nm_len + sizeof(tOptionValue) + 1; - tOptionValue * new_val = AGALOC(sz, "int val"); - - /* - * Scan over whitespace is constrained by "d_len" - */ - while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { - d_len--; val++; - } - if (d_len == 0) - new_val->v.longVal = 0; - else - new_val->v.longVal = strtol(val, 0, 0); - - new_val->valType = OPARG_TYPE_NUMERIC; - new_val->pzName = (char *)(new_val + 1); - memcpy(new_val->pzName, name, nm_len); - new_val->pzName[ nm_len ] = NUL; - addArgListEntry(pp, new_val); - return new_val; -} - -/** - * Associate a name with a nested/hierarchical value. - * - * @param[in,out] pp argument list to add to - * @param[in] name the name of the "suboption" - * @param[in] nm_len the length of the name - * @param[in] val the nested values for the suboption - * @param[in] d_len the length of the value - * - * @returns the new value structure - */ -static tOptionValue * -add_nested(void ** pp, char const * name, size_t nm_len, - char * val, size_t d_len) -{ - tOptionValue * new_val; - - if (d_len == 0) { - size_t sz = nm_len + sizeof(*new_val) + 1; - new_val = AGALOC(sz, "empty nest"); - new_val->v.nestVal = NULL; - new_val->valType = OPARG_TYPE_HIERARCHY; - new_val->pzName = (char *)(new_val + 1); - memcpy(new_val->pzName, name, nm_len); - new_val->pzName[ nm_len ] = NUL; - - } else { - new_val = optionLoadNested(val, name, nm_len); - } - - if (new_val != NULL) - addArgListEntry(pp, new_val); - - return new_val; -} - -/** - * We have an entry that starts with a name. Find the end of it, cook it - * (if called for) and create the name/value association. - */ -static char const * -scan_name(char const * name, tOptionValue * res) -{ - tOptionValue * new_val; - char const * pzScan = name+1; /* we know first char is a name char */ - char const * pzVal; - size_t nm_len = 1; - size_t d_len = 0; - - /* - * Scan over characters that name a value. These names may not end - * with a colon, but they may contain colons. - */ - pzScan = SPN_VALUE_NAME_CHARS(name + 1); - if (pzScan[-1] == ':') - pzScan--; - nm_len = (size_t)(pzScan - name); - - pzScan = SPN_HORIZ_WHITE_CHARS(pzScan); - - re_switch: - - switch (*pzScan) { - case '=': - case ':': - pzScan = SPN_HORIZ_WHITE_CHARS(pzScan + 1); - if ((*pzScan == '=') || (*pzScan == ':')) - goto default_char; - goto re_switch; - - case NL: - case ',': - pzScan++; - /* FALLTHROUGH */ - - case NUL: - add_string(&(res->v.nestVal), name, nm_len, NULL, (size_t)0); - break; - - case '"': - case '\'': - pzVal = pzScan; - pzScan = scan_q_str(pzScan); - d_len = (size_t)(pzScan - pzVal); - new_val = add_string(&(res->v.nestVal), name, nm_len, pzVal, - d_len); - if ((new_val != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) - ao_string_cook(new_val->v.strVal, NULL); - break; - - default: - default_char: - /* - * We have found some strange text value. It ends with a newline - * or a comma. - */ - pzVal = pzScan; - for (;;) { - char ch = *(pzScan++); - switch (ch) { - case NUL: - pzScan--; - d_len = (size_t)(pzScan - pzVal); - goto string_done; - /* FALLTHROUGH */ - - case NL: - if ( (pzScan > pzVal + 2) - && (pzScan[-2] == '\\') - && (pzScan[ 0] != NUL)) - continue; - /* FALLTHROUGH */ - - case ',': - d_len = (size_t)(pzScan - pzVal) - 1; - string_done: - new_val = add_string(&(res->v.nestVal), name, nm_len, - pzVal, d_len); - if (new_val != NULL) - remove_continuation(new_val->v.strVal); - goto leave_scan_name; - } - } - break; - } leave_scan_name:; - - return pzScan; -} - -/** - * Some xml element that does not start with a name. - * The next character must be either '!' (introducing a comment), - * or '?' (introducing an XML meta-marker of some sort). - * We ignore these and indicate an error (NULL result) otherwise. - * - * @param[in] txt the text within an xml bracket - * @returns the address of the character after the closing marker, or NULL. - */ -static char const * -unnamed_xml(char const * txt) -{ - switch (*txt) { - default: - txt = NULL; - break; - - case '!': - txt = strstr(txt, "-->"); - if (txt != NULL) - txt += 3; - break; - - case '?': - txt = strchr(txt, '>'); - if (txt != NULL) - txt++; - break; - } - return txt; -} - -/** - * Scan off the xml element name, and the rest of the header, too. - * Set the value type to NONE if it ends with "/>". - * - * @param[in] name the first name character (alphabetic) - * @param[out] nm_len the length of the name - * @param[out] val set valType field to STRING or NONE. - * - * @returns the scan resumption point, or NULL on error - */ -static char const * -scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val) -{ - char const * scan = SPN_VALUE_NAME_CHARS(name + 1); - *nm_len = (size_t)(scan - name); - if (*nm_len > 64) - return NULL; - val->valType = OPARG_TYPE_STRING; - - if (IS_WHITESPACE_CHAR(*scan)) { - /* - * There are attributes following the name. Parse 'em. - */ - scan = SPN_WHITESPACE_CHARS(scan); - scan = parse_attrs(NULL, scan, &option_load_mode, val); - if (scan == NULL) - return NULL; /* oops */ - } - - if (! IS_END_XML_TOKEN_CHAR(*scan)) - return NULL; /* oops */ - - if (*scan == '/') { - /* - * Single element XML entries get inserted as an empty string. - */ - if (*++scan != '>') - return NULL; - val->valType = OPARG_TYPE_NONE; - } - return scan+1; -} - -/** - * We've found a closing '>' without a preceding '/', thus we must search - * the text for '' where "name" is the name of the XML element. - * - * @param[in] name the start of the name in the element header - * @param[in] nm_len the length of that name - * @param[out] len the length of the value (string between header and - * the trailer/tail. - * @returns the character after the trailer, or NULL if not found. - */ -static char const * -find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len) -{ - char z[72] = " 0); /* nm_len is known to be 64 or less */ - *(dst++) = '>'; - *dst = NUL; - - { - char const * res = strstr(val, z); - - if (res != NULL) { - char const * end = (option_load_mode != OPTION_LOAD_KEEP) - ? SPN_WHITESPACE_BACK(val, res) - : res; - *len = (size_t)(end - val); /* includes trailing white space */ - res = SPN_WHITESPACE_CHARS(res + (dst - z)); - } - return res; - } -} - -/** - * We've found a '<' character. We ignore this if it is a comment or a - * directive. If it is something else, then whatever it is we are looking - * at is bogus. Returning NULL stops processing. - * - * @param[in] xml_name the name of an xml bracket (usually) - * @param[in,out] res_val the option data derived from the XML element - * - * @returns the place to resume scanning input - */ -static char const * -scan_xml(char const * xml_name, tOptionValue * res_val) -{ - size_t nm_len, v_len; - char const * scan; - char const * val_str; - tOptionValue valu; - tOptionLoadMode save_mode = option_load_mode; - - if (! IS_VAR_FIRST_CHAR(*++xml_name)) - return unnamed_xml(xml_name); - - /* - * "scan_xml_name()" may change "option_load_mode". - */ - val_str = scan_xml_name(xml_name, &nm_len, &valu); - if (val_str == NULL) - goto bail_scan_xml; - - if (valu.valType == OPARG_TYPE_NONE) - scan = val_str; - else { - if (option_load_mode != OPTION_LOAD_KEEP) - val_str = SPN_WHITESPACE_CHARS(val_str); - scan = find_end_xml(xml_name, nm_len, val_str, &v_len); - if (scan == NULL) - goto bail_scan_xml; - } - - /* - * "scan" now points to where the scan is to resume after returning. - * It either points after "/>" at the end of the XML element header, - * or it points after the "" tail based on the name in the header. - */ - - switch (valu.valType) { - case OPARG_TYPE_NONE: - add_string(&(res_val->v.nestVal), xml_name, nm_len, NULL, 0); - break; - - case OPARG_TYPE_STRING: - { - tOptionValue * new_val = add_string( - &(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); - - if (option_load_mode != OPTION_LOAD_KEEP) - munge_str(new_val->v.strVal, option_load_mode); - - break; - } - - case OPARG_TYPE_BOOLEAN: - add_bool(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); - break; - - case OPARG_TYPE_NUMERIC: - add_number(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); - break; - - case OPARG_TYPE_HIERARCHY: - { - char * pz = AGALOC(v_len+1, "h scan"); - memcpy(pz, val_str, v_len); - pz[v_len] = NUL; - add_nested(&(res_val->v.nestVal), xml_name, nm_len, pz, v_len); - AGFREE(pz); - break; - } - - case OPARG_TYPE_ENUMERATION: - case OPARG_TYPE_MEMBERSHIP: - default: - break; - } - - option_load_mode = save_mode; - return scan; - -bail_scan_xml: - option_load_mode = save_mode; - return NULL; -} - - -/** - * Deallocate a list of option arguments. This must have been gotten from - * a hierarchical option argument, not a stacked list of strings. It is - * an internal call, so it is not validated. The caller is responsible for - * knowing what they are doing. - */ -static void -unload_arg_list(tArgList * arg_list) -{ - int ct = arg_list->useCt; - char const ** pnew_val = arg_list->apzArgs; - - while (ct-- > 0) { - tOptionValue * new_val = (tOptionValue *)VOIDP(*(pnew_val++)); - if (new_val->valType == OPARG_TYPE_HIERARCHY) - unload_arg_list(new_val->v.nestVal); - AGFREE(new_val); - } - - AGFREE(arg_list); -} - -/*=export_func optionUnloadNested - * - * what: Deallocate the memory for a nested value - * arg: + tOptionValue const * + pOptVal + the hierarchical value + - * - * doc: - * A nested value needs to be deallocated. The pointer passed in should - * have been gotten from a call to @code{configFileLoad()} (See - * @pxref{libopts-configFileLoad}). -=*/ -void -optionUnloadNested(tOptionValue const * opt_val) -{ - if (opt_val == NULL) return; - if (opt_val->valType != OPARG_TYPE_HIERARCHY) { - errno = EINVAL; - return; - } - - unload_arg_list(opt_val->v.nestVal); - - AGFREE(opt_val); -} - -/** - * This is a _stable_ sort. The entries are sorted alphabetically, - * but within entries of the same name the ordering is unchanged. - * Typically, we also hope the input is sorted. - */ -static void -sort_list(tArgList * arg_list) -{ - int ix; - int lm = arg_list->useCt; - - /* - * This loop iterates "useCt" - 1 times. - */ - for (ix = 0; ++ix < lm;) { - int iy = ix-1; - tOptionValue * new_v = C(tOptionValue *, arg_list->apzArgs[ix]); - tOptionValue * old_v = C(tOptionValue *, arg_list->apzArgs[iy]); - - /* - * For as long as the new entry precedes the "old" entry, - * move the old pointer. Stop before trying to extract the - * "-1" entry. - */ - while (strcmp(old_v->pzName, new_v->pzName) > 0) { - arg_list->apzArgs[iy+1] = VOIDP(old_v); - old_v = (tOptionValue *)VOIDP(arg_list->apzArgs[--iy]); - if (iy < 0) - break; - } - - /* - * Always store the pointer. Sometimes it is redundant, - * but the redundancy is cheaper than a test and branch sequence. - */ - arg_list->apzArgs[iy+1] = VOIDP(new_v); - } -} - -/*= - * private: - * - * what: parse a hierarchical option argument - * arg: + char const * + pzTxt + the text to scan + - * arg: + char const * + pzName + the name for the text + - * arg: + size_t + nm_len + the length of "name" + - * - * ret_type: tOptionValue * - * ret_desc: An allocated, compound value structure - * - * doc: - * A block of text represents a series of values. It may be an - * entire configuration file, or it may be an argument to an - * option that takes a hierarchical value. - * - * If NULL is returned, errno will be set: - * @itemize @bullet - * @item - * @code{EINVAL} the input text was NULL. - * @item - * @code{ENOMEM} the storage structures could not be allocated - * @item - * @code{ENOMSG} no configuration values were found - * @end itemize -=*/ -static tOptionValue * -optionLoadNested(char const * text, char const * name, size_t nm_len) -{ - tOptionValue * res_val; - - /* - * Make sure we have some data and we have space to put what we find. - */ - if (text == NULL) { - errno = EINVAL; - return NULL; - } - text = SPN_WHITESPACE_CHARS(text); - if (*text == NUL) { - errno = ENOMSG; - return NULL; - } - res_val = AGALOC(sizeof(*res_val) + nm_len + 1, "nest args"); - res_val->valType = OPARG_TYPE_HIERARCHY; - res_val->pzName = (char *)(res_val + 1); - memcpy(res_val->pzName, name, nm_len); - res_val->pzName[nm_len] = NUL; - - { - tArgList * arg_list = AGALOC(sizeof(*arg_list), "nest arg l"); - - res_val->v.nestVal = arg_list; - arg_list->useCt = 0; - arg_list->allocCt = MIN_ARG_ALLOC_CT; - } - - /* - * Scan until we hit a NUL. - */ - do { - text = SPN_WHITESPACE_CHARS(text); - if (IS_VAR_FIRST_CHAR(*text)) - text = scan_name(text, res_val); - - else switch (*text) { - case NUL: - goto scan_done; - - case '<': - text = scan_xml(text, res_val); - if (text == NULL) - goto woops; - if (*text == ',') - text++; - break; - - case '#': - text = strchr(text, NL); - break; - - default: - goto woops; - } - } while (text != NULL); scan_done:; - - { - tArgList * al = res_val->v.nestVal; - if (al->useCt == 0) { - errno = ENOMSG; - goto woops; - } - if (al->useCt > 1) - sort_list(al); - } - - return res_val; - - woops: - AGFREE(res_val->v.nestVal); - AGFREE(res_val); - return NULL; -} - -/*=export_func optionNestedVal - * private: - * - * what: parse a hierarchical option argument - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Nested value was found on the command line -=*/ -void -optionNestedVal(tOptions * opts, tOptDesc * od) -{ - if (opts < OPTPROC_EMIT_LIMIT) - return; - - if (od->fOptState & OPTST_RESET) { - tArgList * arg_list = od->optCookie; - int ct; - char const ** av; - - if (arg_list == NULL) - return; - ct = arg_list->useCt; - av = arg_list->apzArgs; - - while (--ct >= 0) { - void * p = VOIDP(*(av++)); - optionUnloadNested((tOptionValue const *)p); - } - - AGFREE(od->optCookie); - - } else { - tOptionValue * opt_val = optionLoadNested( - od->optArg.argString, od->pz_Name, strlen(od->pz_Name)); - - if (opt_val != NULL) - addArgListEntry(&(od->optCookie), VOIDP(opt_val)); - } -} - -/** - * get_special_char - */ -static int -get_special_char(char const ** ppz, int * ct) -{ - char const * pz = *ppz; - - if (*ct < 3) - return '&'; - - if (*pz == '#') { - int base = 10; - int retch; - - pz++; - if (*pz == 'x') { - base = 16; - pz++; - } - retch = (int)strtoul(pz, (char **)&pz, base); - if (*pz != ';') - return '&'; - base = (int)(++pz - *ppz); - if (base > *ct) - return '&'; - - *ct -= base; - *ppz = pz; - return retch; - } - - { - int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); - xml_xlate_t const * xlatp = xml_xlate; - - for (;;) { - if ( (*ct >= xlatp->xml_len) - && (strncmp(pz, xlatp->xml_txt, (size_t)xlatp->xml_len) == 0)) { - *ppz += xlatp->xml_len; - *ct -= xlatp->xml_len; - return xlatp->xml_ch; - } - - if (--ctr <= 0) - break; - xlatp++; - } - } - return '&'; -} - -/** - * emit_special_char - */ -static void -emit_special_char(FILE * fp, int ch) -{ - int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); - xml_xlate_t const * xlatp = xml_xlate; - - putc('&', fp); - for (;;) { - if (ch == xlatp->xml_ch) { - fputs(xlatp->xml_txt, fp); - return; - } - if (--ctr <= 0) - break; - xlatp++; - } - fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF)); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/nested.c */ diff --git a/src/libopts/numeric.c b/src/libopts/numeric.c deleted file mode 100644 index bbb43cc..0000000 --- a/src/libopts/numeric.c +++ /dev/null @@ -1,180 +0,0 @@ - -/** - * \file numeric.c - * - * Handle options with numeric (integer) arguments. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/*=export_func optionShowRange - * private: - * - * what: Show info about range constraints - * arg: + tOptions * + pOpts + program options descriptor + - * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + - * arg: + void * + rng_table + the value range tables + - * arg: + int + rng_count + the number of entries + - * - * doc: - * Show information about a numeric option with range constraints. -=*/ -void -optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct) -{ - const struct {long const rmin, rmax;} * rng = rng_table; - - char const * pz_indent = zTabHyp + tab_skip_ct; - - /* - * The range is shown only for full usage requests and an error - * in this particular option. - */ - if (pOpts != OPTPROC_EMIT_USAGE) { - if (pOpts <= OPTPROC_EMIT_LIMIT) - return; - pz_indent = ONE_TAB_STR; - - fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, - pOD->pz_Name, pOD->optArg.argInt); - pz_indent = ""; - } - - if (pOD->fOptState & OPTST_SCALED_NUM) - fprintf(option_usage_fp, zRangeScaled, pz_indent); - - fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); - pz_indent = (pOpts != OPTPROC_EMIT_USAGE) - ? ONE_TAB_STR - : (zTabSpace + tab_skip_ct); - - for (;;) { - if (rng->rmax == LONG_MIN) - fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); - else if (rng->rmin == LONG_MIN) - fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); - else if (rng->rmax == LONG_MAX) - fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); - else - fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, - rng->rmax); - - if (--rng_ct <= 0) { - fputc(NL, option_usage_fp); - break; - } - fputs(zRangeOr, option_usage_fp); - rng++; - } - - if (pOpts > OPTPROC_EMIT_LIMIT) - pOpts->pUsageProc(pOpts, EXIT_FAILURE); -} - -/*=export_func optionNumericVal - * private: - * - * what: process an option with a numeric value. - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Decipher a numeric value. -=*/ -void -optionNumericVal(tOptions * opts, tOptDesc * od) -{ - char * pz; - long val; - - /* - * Guard against all the different ways this procedure might get invoked - * when there is no string argument provided. - */ - if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) - return; - - /* - * Numeric options may have a range associated with it. - * If it does, the usage procedure requests that it be - * emitted by passing a NULL od pointer. Also bail out - * if there is no option argument or if we are being reset. - */ - if ( (od == NULL) - || (od->optArg.argString == NULL) - || ((od->fOptState & OPTST_RESET) != 0) - || (opts <= OPTPROC_EMIT_LIMIT)) - return; - - errno = 0; - val = strtol(od->optArg.argString, &pz, 0); - if ((pz == od->optArg.argString) || (errno != 0)) - goto bad_number; - - if ((od->fOptState & OPTST_SCALED_NUM) != 0) - switch (*(pz++)) { - case NUL: pz--; break; - case 't': val *= 1000; /* FALLTHROUGH */ - case 'g': val *= 1000; /* FALLTHROUGH */ - case 'm': val *= 1000; /* FALLTHROUGH */ - case 'k': val *= 1000; break; - - case 'T': val *= 1024; /* FALLTHROUGH */ - case 'G': val *= 1024; /* FALLTHROUGH */ - case 'M': val *= 1024; /* FALLTHROUGH */ - case 'K': val *= 1024; break; - - default: goto bad_number; - } - - if (*pz != NUL) - goto bad_number; - - if (od->fOptState & OPTST_ALLOC_ARG) { - AGFREE(od->optArg.argString); - od->fOptState &= ~OPTST_ALLOC_ARG; - } - - od->optArg.argInt = val; - return; - - bad_number: - - fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - (*(opts->pUsageProc))(opts, EXIT_FAILURE); - - errno = EINVAL; - od->optArg.argInt = ~0; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/numeric.c */ diff --git a/src/libopts/option-value-type.c b/src/libopts/option-value-type.c deleted file mode 100644 index 2bc8642..0000000 --- a/src/libopts/option-value-type.c +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (stdin.c) - * - * It has been AutoGen-ed - * From the definitions stdin - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - */ -#include "option-value-type.h" -/* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf option-value-type.gp */ -/* Computed positions: -k'1' */ - - - -# if 0 /* gperf build options: */ -// %struct-type -// %language=ANSI-C -// %includes -// %global-table -// %omit-struct-type -// %readonly-tables -// %compare-strncmp -// -// %define slot-name vtp_name -// %define hash-function-name option_value_type_hash -// %define lookup-function-name find_option_value_type_name -// %define word-array-name option_value_type_table -// %define initializer-suffix ,VTP_COUNT_CMD -// -# endif - -#include "option-value-type.h" -typedef struct { - char const * vtp_name; - option_value_type_enum_t vtp_id; -} option_value_type_map_t; -#include - -/* maximum key range = 15, duplicates = 0 */ - -static unsigned int -option_value_type_hash (register const char *str, register size_t len) -{ - static const unsigned char asso_values[] = - { - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 0, 18, - 18, 18, 18, 18, 0, 10, 18, 5, 18, 18, - 5, 18, 18, 18, 18, 0, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18 - }; - return len + asso_values[(unsigned char)str[0]]; -} - -static const option_value_type_map_t option_value_type_table[] = - { - {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, - {"",VTP_COUNT_CMD}, - {"set", VTP_CMD_SET}, - {"bool", VTP_CMD_BOOL}, - {"",VTP_COUNT_CMD}, - {"string", VTP_CMD_STRING}, - {"boolean", VTP_CMD_BOOLEAN}, - {"",VTP_COUNT_CMD}, - {"hierarchy", VTP_CMD_HIERARCHY}, - {"",VTP_COUNT_CMD}, - {"nested", VTP_CMD_NESTED}, - {"keyword", VTP_CMD_KEYWORD}, - {"",VTP_COUNT_CMD}, - {"set-membership", VTP_CMD_SET_MEMBERSHIP}, - {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, - {"integer", VTP_CMD_INTEGER} - }; - -static inline const option_value_type_map_t * -find_option_value_type_name (register const char *str, register size_t len) -{ - if (len <= 14 && len >= 3) - { - register unsigned int key = (int)option_value_type_hash (str, len); - - if (key <= 17) - { - register const char *s = option_value_type_table[key].vtp_name; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &option_value_type_table[key]; - } - } - return 0; -} - -/** - * Convert a command (keyword) to a option_value_type_enum_t enumeration value. - * - * @param[in] str a string that should start with a known key word. - * @param[in] len the provided length of the keyword at \a str. - * @returns the enumeration value. - * If not found, that value is VTP_INVALID_CMD. - */ -option_value_type_enum_t -find_option_value_type_cmd(char const * str, size_t len) -{ - option_value_type_map_t const * map; - - map = find_option_value_type_name(str, (unsigned int)len); - return (map == NULL) ? VTP_INVALID_CMD : map->vtp_id; -} - -/* end of option-value-type.c */ diff --git a/src/libopts/option-value-type.h b/src/libopts/option-value-type.h deleted file mode 100644 index cf6dcaa..0000000 --- a/src/libopts/option-value-type.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (stdin.h) - * - * It has been AutoGen-ed - * From the definitions stdin - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - * - * Command/Keyword Dispatcher - */ -#ifndef STR2ENUM_OPTION_VALUE_TYPE_H_GUARD -#define STR2ENUM_OPTION_VALUE_TYPE_H_GUARD 1 -#include -#ifndef MISSING_INTTYPES_H -# include -#endif - -typedef enum { - VTP_INVALID_CMD = 0, - VTP_CMD_STRING = 1, - VTP_CMD_INTEGER = 2, - VTP_CMD_BOOL = 3, - VTP_CMD_BOOLEAN = 4, - VTP_CMD_KEYWORD = 5, - VTP_CMD_SET = 6, - VTP_CMD_SET_MEMBERSHIP = 7, - VTP_CMD_NESTED = 8, - VTP_CMD_HIERARCHY = 9, - VTP_COUNT_CMD -} option_value_type_enum_t; - -extern option_value_type_enum_t -find_option_value_type_cmd(char const * str, size_t len); - -#endif /* STR2ENUM_OPTION_VALUE_TYPE_H_GUARD */ -/* end of option-value-type.h */ diff --git a/src/libopts/option-xat-attribute.c b/src/libopts/option-xat-attribute.c deleted file mode 100644 index a34ab1b..0000000 --- a/src/libopts/option-xat-attribute.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (stdin.c) - * - * It has been AutoGen-ed - * From the definitions stdin - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - */ -#include "option-xat-attribute.h" -/* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf option-xat-attribute.gp */ -/* Computed positions: -k'1' */ - - - -# if 0 /* gperf build options: */ -// %struct-type -// %language=ANSI-C -// %includes -// %global-table -// %omit-struct-type -// %readonly-tables -// %compare-strncmp -// -// %define slot-name xat_name -// %define hash-function-name option_xat_attribute_hash -// %define lookup-function-name find_option_xat_attribute_name -// %define word-array-name option_xat_attribute_table -// %define initializer-suffix ,XAT_COUNT_CMD -// -# endif - -#include "option-xat-attribute.h" -typedef struct { - char const * xat_name; - option_xat_attribute_enum_t xat_id; -} option_xat_attribute_map_t; -#include - -/* maximum key range = 6, duplicates = 0 */ - -static unsigned int -option_xat_attribute_hash (register const char *str, register size_t len) -{ - static const unsigned char asso_values[] = - { - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10, 0, - 10,10,10,10,10,10,10, 5,10, 0, - 10,10,10,10,10,10, 0, 0,10, 0, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10 - }; - return len + asso_values[(unsigned char)str[0]]; -} - -static const option_xat_attribute_map_t option_xat_attribute_table[] = - { - {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, - {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, - {"type", XAT_CMD_TYPE}, - {"words", XAT_CMD_WORDS}, - {"cooked", XAT_CMD_COOKED}, - {"members", XAT_CMD_MEMBERS}, - {"uncooked", XAT_CMD_UNCOOKED}, - {"keep", XAT_CMD_KEEP} - }; - -static inline const option_xat_attribute_map_t * -find_option_xat_attribute_name (register const char *str, register size_t len) -{ - if (len <= 8 && len >= 4) - { - register unsigned int key = (int)option_xat_attribute_hash (str, len); - - if (key <= 9) - { - register const char *s = option_xat_attribute_table[key].xat_name; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &option_xat_attribute_table[key]; - } - } - return 0; -} - -/** - * Convert a command (keyword) to a option_xat_attribute_enum_t enumeration value. - * - * @param[in] str a string that should start with a known key word. - * @param[in] len the provided length of the keyword at \a str. - * @returns the enumeration value. - * If not found, that value is XAT_INVALID_CMD. - */ -option_xat_attribute_enum_t -find_option_xat_attribute_cmd(char const * str, size_t len) -{ - option_xat_attribute_map_t const * map; - - map = find_option_xat_attribute_name(str, (unsigned int)len); - return (map == NULL) ? XAT_INVALID_CMD : map->xat_id; -} - -/* end of option-xat-attribute.c */ diff --git a/src/libopts/option-xat-attribute.h b/src/libopts/option-xat-attribute.h deleted file mode 100644 index dde1617..0000000 --- a/src/libopts/option-xat-attribute.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (stdin.h) - * - * It has been AutoGen-ed - * From the definitions stdin - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - * - * Command/Keyword Dispatcher - */ -#ifndef STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD -#define STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD 1 -#include -#ifndef MISSING_INTTYPES_H -# include -#endif - -typedef enum { - XAT_INVALID_CMD = 0, - XAT_CMD_TYPE = 1, - XAT_CMD_WORDS = 2, - XAT_CMD_MEMBERS = 3, - XAT_CMD_COOKED = 4, - XAT_CMD_UNCOOKED = 5, - XAT_CMD_KEEP = 6, - XAT_COUNT_CMD -} option_xat_attribute_enum_t; - -extern option_xat_attribute_enum_t -find_option_xat_attribute_cmd(char const * str, size_t len); - -#endif /* STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD */ -/* end of option-xat-attribute.h */ diff --git a/src/libopts/parse-duration.c b/src/libopts/parse-duration.c deleted file mode 100644 index 0f4a056..0000000 --- a/src/libopts/parse-duration.c +++ /dev/null @@ -1,604 +0,0 @@ -/* Parse a time duration and return a seconds count - Copyright (C) 2008-2018 Free Software Foundation, Inc. - Written by Bruce Korb , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . */ - -#include - -/* Specification. */ -#include "parse-duration.h" - -#include -#include -#include -#include -#include -#include - -#include "intprops.h" - -#ifndef NUL -#define NUL '\0' -#endif - -#define cch_t char const - -typedef enum { - NOTHING_IS_DONE, - YEAR_IS_DONE, - MONTH_IS_DONE, - WEEK_IS_DONE, - DAY_IS_DONE, - HOUR_IS_DONE, - MINUTE_IS_DONE, - SECOND_IS_DONE -} whats_done_t; - -#define SEC_PER_MIN 60 -#define SEC_PER_HR (SEC_PER_MIN * 60) -#define SEC_PER_DAY (SEC_PER_HR * 24) -#define SEC_PER_WEEK (SEC_PER_DAY * 7) -#define SEC_PER_MONTH (SEC_PER_DAY * 30) -#define SEC_PER_YEAR (SEC_PER_DAY * 365) - -#undef MAX_DURATION -#define MAX_DURATION TYPE_MAXIMUM(time_t) - -/* Wrapper around strtoul that does not require a cast. */ -static unsigned long -str_const_to_ul (cch_t * str, cch_t ** ppz, int base) -{ - return strtoul (str, (char **)ppz, base); -} - -/* Wrapper around strtol that does not require a cast. */ -static long -str_const_to_l (cch_t * str, cch_t ** ppz, int base) -{ - return strtol (str, (char **)ppz, base); -} - -/* Returns BASE + VAL * SCALE, interpreting BASE = BAD_TIME - with errno set as an error situation, and returning BAD_TIME - with errno set in an error situation. */ -static time_t -scale_n_add (time_t base, time_t val, int scale) -{ - if (base == BAD_TIME) - { - if (errno == 0) - errno = EINVAL; - return BAD_TIME; - } - - if (val > MAX_DURATION / scale) - { - errno = ERANGE; - return BAD_TIME; - } - - val *= scale; - if (base > MAX_DURATION - val) - { - errno = ERANGE; - return BAD_TIME; - } - - return base + val; -} - -/* After a number HH has been parsed, parse subsequent :MM or :MM:SS. */ -static time_t -parse_hr_min_sec (time_t start, cch_t * pz) -{ - int lpct = 0; - - errno = 0; - - /* For as long as our scanner pointer points to a colon *AND* - we've not looped before, then keep looping. (two iterations max) */ - while ((*pz == ':') && (lpct++ <= 1)) - { - unsigned long v = str_const_to_ul (pz+1, &pz, 10); - - if (errno != 0) - return BAD_TIME; - - start = scale_n_add (v, start, 60); - - if (errno != 0) - return BAD_TIME; - } - - /* allow for trailing spaces */ - while (isspace ((unsigned char)*pz)) - pz++; - if (*pz != NUL) - { - errno = EINVAL; - return BAD_TIME; - } - - return start; -} - -/* Parses a value and returns BASE + value * SCALE, interpreting - BASE = BAD_TIME with errno set as an error situation, and returning - BAD_TIME with errno set in an error situation. */ -static time_t -parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale) -{ - cch_t * pz = *ppz; - time_t val; - - if (base == BAD_TIME) - return base; - - errno = 0; - val = str_const_to_ul (pz, &pz, 10); - if (errno != 0) - return BAD_TIME; - while (isspace ((unsigned char)*pz)) - pz++; - if (pz != endp) - { - errno = EINVAL; - return BAD_TIME; - } - - *ppz = pz; - return scale_n_add (base, val, scale); -} - -/* Parses the syntax YEAR-MONTH-DAY. - PS points into the string, after "YEAR", before "-MONTH-DAY". */ -static time_t -parse_year_month_day (cch_t * pz, cch_t * ps) -{ - time_t res = 0; - - res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); - - pz++; /* over the first '-' */ - ps = strchr (pz, '-'); - if (ps == NULL) - { - errno = EINVAL; - return BAD_TIME; - } - res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); - - pz++; /* over the second '-' */ - ps = pz + strlen (pz); - return parse_scaled_value (res, &pz, ps, SEC_PER_DAY); -} - -/* Parses the syntax YYYYMMDD. */ -static time_t -parse_yearmonthday (cch_t * in_pz) -{ - time_t res = 0; - char buf[8]; - cch_t * pz; - - if (strlen (in_pz) != 8) - { - errno = EINVAL; - return BAD_TIME; - } - - memcpy (buf, in_pz, 4); - buf[4] = NUL; - pz = buf; - res = parse_scaled_value (0, &pz, buf + 4, SEC_PER_YEAR); - - memcpy (buf, in_pz + 4, 2); - buf[2] = NUL; - pz = buf; - res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MONTH); - - memcpy (buf, in_pz + 6, 2); - buf[2] = NUL; - pz = buf; - return parse_scaled_value (res, &pz, buf + 2, SEC_PER_DAY); -} - -/* Parses the syntax yy Y mm M ww W dd D. */ -static time_t -parse_YMWD (cch_t * pz) -{ - time_t res = 0; - cch_t * ps = strchr (pz, 'Y'); - if (ps != NULL) - { - res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); - pz++; - } - - ps = strchr (pz, 'M'); - if (ps != NULL) - { - res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); - pz++; - } - - ps = strchr (pz, 'W'); - if (ps != NULL) - { - res = parse_scaled_value (res, &pz, ps, SEC_PER_WEEK); - pz++; - } - - ps = strchr (pz, 'D'); - if (ps != NULL) - { - res = parse_scaled_value (res, &pz, ps, SEC_PER_DAY); - pz++; - } - - while (isspace ((unsigned char)*pz)) - pz++; - if (*pz != NUL) - { - errno = EINVAL; - return BAD_TIME; - } - - return res; -} - -/* Parses the syntax HH:MM:SS. - PS points into the string, after "HH", before ":MM:SS". */ -static time_t -parse_hour_minute_second (cch_t * pz, cch_t * ps) -{ - time_t res = 0; - - res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); - - pz++; - ps = strchr (pz, ':'); - if (ps == NULL) - { - errno = EINVAL; - return BAD_TIME; - } - - res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); - - pz++; - ps = pz + strlen (pz); - return parse_scaled_value (res, &pz, ps, 1); -} - -/* Parses the syntax HHMMSS. */ -static time_t -parse_hourminutesecond (cch_t * in_pz) -{ - time_t res = 0; - char buf[4]; - cch_t * pz; - - if (strlen (in_pz) != 6) - { - errno = EINVAL; - return BAD_TIME; - } - - memcpy (buf, in_pz, 2); - buf[2] = NUL; - pz = buf; - res = parse_scaled_value (0, &pz, buf + 2, SEC_PER_HR); - - memcpy (buf, in_pz + 2, 2); - buf[2] = NUL; - pz = buf; - res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MIN); - - memcpy (buf, in_pz + 4, 2); - buf[2] = NUL; - pz = buf; - return parse_scaled_value (res, &pz, buf + 2, 1); -} - -/* Parses the syntax hh H mm M ss S. */ -static time_t -parse_HMS (cch_t * pz) -{ - time_t res = 0; - cch_t * ps = strchr (pz, 'H'); - if (ps != NULL) - { - res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); - pz++; - } - - ps = strchr (pz, 'M'); - if (ps != NULL) - { - res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); - pz++; - } - - ps = strchr (pz, 'S'); - if (ps != NULL) - { - res = parse_scaled_value (res, &pz, ps, 1); - pz++; - } - - while (isspace ((unsigned char)*pz)) - pz++; - if (*pz != NUL) - { - errno = EINVAL; - return BAD_TIME; - } - - return res; -} - -/* Parses a time (hours, minutes, seconds) specification in either syntax. */ -static time_t -parse_time (cch_t * pz) -{ - cch_t * ps; - time_t res = 0; - - /* - * Scan for a hyphen - */ - ps = strchr (pz, ':'); - if (ps != NULL) - { - res = parse_hour_minute_second (pz, ps); - } - - /* - * Try for a 'H', 'M' or 'S' suffix - */ - else if (ps = strpbrk (pz, "HMS"), - ps == NULL) - { - /* Its a YYYYMMDD format: */ - res = parse_hourminutesecond (pz); - } - - else - res = parse_HMS (pz); - - return res; -} - -/* Returns a substring of the given string, with spaces at the beginning and at - the end destructively removed, per SNOBOL. */ -static char * -trim (char * pz) -{ - /* trim leading white space */ - while (isspace ((unsigned char)*pz)) - pz++; - - /* trim trailing white space */ - { - char * pe = pz + strlen (pz); - while ((pe > pz) && isspace ((unsigned char)pe[-1])) - pe--; - *pe = NUL; - } - - return pz; -} - -/* - * Parse the year/months/days of a time period - */ -static time_t -parse_period (cch_t * in_pz) -{ - char * pT; - char * ps; - char * pz = strdup (in_pz); - void * fptr = pz; - time_t res = 0; - - if (pz == NULL) - { - errno = ENOMEM; - return BAD_TIME; - } - - pT = strchr (pz, 'T'); - if (pT != NULL) - { - *(pT++) = NUL; - pz = trim (pz); - pT = trim (pT); - } - - /* - * Scan for a hyphen - */ - ps = strchr (pz, '-'); - if (ps != NULL) - { - res = parse_year_month_day (pz, ps); - } - - /* - * Try for a 'Y', 'M' or 'D' suffix - */ - else if (ps = strpbrk (pz, "YMWD"), - ps == NULL) - { - /* Its a YYYYMMDD format: */ - res = parse_yearmonthday (pz); - } - - else - res = parse_YMWD (pz); - - if ((errno == 0) && (pT != NULL)) - { - time_t val = parse_time (pT); - res = scale_n_add (res, val, 1); - } - - free (fptr); - return res; -} - -static time_t -parse_non_iso8601 (cch_t * pz) -{ - whats_done_t whatd_we_do = NOTHING_IS_DONE; - - time_t res = 0; - - do { - time_t val; - - errno = 0; - val = str_const_to_l (pz, &pz, 10); - if (errno != 0) - goto bad_time; - - /* IF we find a colon, then we're going to have a seconds value. - We will not loop here any more. We cannot already have parsed - a minute value and if we've parsed an hour value, then the result - value has to be less than an hour. */ - if (*pz == ':') - { - if (whatd_we_do >= MINUTE_IS_DONE) - break; - - val = parse_hr_min_sec (val, pz); - - if ((whatd_we_do == HOUR_IS_DONE) && (val >= SEC_PER_HR)) - break; - - return scale_n_add (res, val, 1); - } - - { - unsigned int mult; - - /* Skip over white space following the number we just parsed. */ - while (isspace ((unsigned char)*pz)) - pz++; - - switch (*pz) - { - default: goto bad_time; - case NUL: - return scale_n_add (res, val, 1); - - case 'y': case 'Y': - if (whatd_we_do >= YEAR_IS_DONE) - goto bad_time; - mult = SEC_PER_YEAR; - whatd_we_do = YEAR_IS_DONE; - break; - - case 'M': - if (whatd_we_do >= MONTH_IS_DONE) - goto bad_time; - mult = SEC_PER_MONTH; - whatd_we_do = MONTH_IS_DONE; - break; - - case 'W': - if (whatd_we_do >= WEEK_IS_DONE) - goto bad_time; - mult = SEC_PER_WEEK; - whatd_we_do = WEEK_IS_DONE; - break; - - case 'd': case 'D': - if (whatd_we_do >= DAY_IS_DONE) - goto bad_time; - mult = SEC_PER_DAY; - whatd_we_do = DAY_IS_DONE; - break; - - case 'h': - if (whatd_we_do >= HOUR_IS_DONE) - goto bad_time; - mult = SEC_PER_HR; - whatd_we_do = HOUR_IS_DONE; - break; - - case 'm': - if (whatd_we_do >= MINUTE_IS_DONE) - goto bad_time; - mult = SEC_PER_MIN; - whatd_we_do = MINUTE_IS_DONE; - break; - - case 's': - mult = 1; - whatd_we_do = SECOND_IS_DONE; - break; - } - - res = scale_n_add (res, val, mult); - - pz++; - while (isspace ((unsigned char)*pz)) - pz++; - if (*pz == NUL) - return res; - - if (! isdigit ((unsigned char)*pz)) - break; - } - - } while (whatd_we_do < SECOND_IS_DONE); - - bad_time: - errno = EINVAL; - return BAD_TIME; -} - -time_t -parse_duration (char const * pz) -{ - while (isspace ((unsigned char)*pz)) - pz++; - - switch (*pz) - { - case 'P': - return parse_period (pz + 1); - - case 'T': - return parse_time (pz + 1); - - default: - if (isdigit ((unsigned char)*pz)) - return parse_non_iso8601 (pz); - - errno = EINVAL; - return BAD_TIME; - } -} - -/* - * Local Variables: - * mode: C - * c-file-style: "gnu" - * indent-tabs-mode: nil - * End: - * end of parse-duration.c */ diff --git a/src/libopts/parse-duration.h b/src/libopts/parse-duration.h deleted file mode 100644 index 9a7bcd5..0000000 --- a/src/libopts/parse-duration.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Parse a time duration and return a seconds count - Copyright (C) 2008-2018 Free Software Foundation, Inc. - Written by Bruce Korb , 2008. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . */ - -/* - - Readers and users of this function are referred to the ISO-8601 - specification, with particular attention to "Durations". - - At the time of writing, this worked: - - https://en.wikipedia.org/wiki/ISO_8601#Durations - - The string must start with a 'P', 'T' or a digit. - - ==== if it is a digit - - the string may contain: NNN Y NNN M NNN W NNN d NNN h NNN m NNN s - This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours, - NNN minutes and NNN seconds. - The embedded white space is optional. - These terms must appear in this order. - Case is significant: 'M' is months and 'm' is minutes. - The final "s" is optional. - All of the terms ("NNN" plus designator) are optional. - Minutes and seconds may optionally be represented as NNN:NNN. - Also, hours, minute and seconds may be represented as NNN:NNN:NNN. - There is no limitation on the value of any of the terms, except - that the final result must fit in a time_t value. - - ==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition. - - The 'P' term may be followed by any of three formats: - yyyymmdd - yy-mm-dd - yy Y mm M ww W dd D - - or it may be empty and followed by a 'T'. The "yyyymmdd" must be eight - digits long. - - NOTE! Months are always 30 days and years are always 365 days long. - 5 years is always 1825 days, not 1826 or 1827 depending on leap year - considerations. 3 months is always 90 days. There is no consideration - for how many days are in the current, next or previous months. - - For the final format: - * Embedded white space is allowed, but it is optional. - * All of the terms are optional. Any or all-but-one may be omitted. - * The meanings are yy years, mm months, ww weeks and dd days. - * The terms must appear in this order. - - ==== The 'T' term may be followed by any of these formats: - - hhmmss - hh:mm:ss - hh H mm M ss S - - For the final format: - * Embedded white space is allowed, but it is optional. - * All of the terms are optional. Any or all-but-one may be omitted. - * The terms must appear in this order. - - */ -#ifndef GNULIB_PARSE_DURATION_H -#define GNULIB_PARSE_DURATION_H - -#include - -/* Return value when a valid duration cannot be parsed. */ -#define BAD_TIME ((time_t)~0) - -/* Parses the given string. If it has the syntax of a valid duration, - this duration is returned. Otherwise, the return value is BAD_TIME, - and errno is set to either EINVAL (bad syntax) or ERANGE (out of range). */ -extern time_t parse_duration (char const * in_pz); - -#endif /* GNULIB_PARSE_DURATION_H */ diff --git a/src/libopts/pgusage.c b/src/libopts/pgusage.c deleted file mode 100644 index f895b3b..0000000 --- a/src/libopts/pgusage.c +++ /dev/null @@ -1,187 +0,0 @@ - -/** - * \file pgusage.c - * - * Automated Options Paged Usage module. - * - * @addtogroup autoopts - * @{ - */ -/* - * This routine will run run-on options through a pager so the - * user may examine, print or edit them at their leisure. - * - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -#if defined(HAVE_WORKING_FORK) -static inline FILE * -open_tmp_usage(char ** buf) -{ - char * bf; - size_t bfsz; - - { - unsigned int my_pid = (unsigned int)getpid(); - char const * tmpdir = getenv(TMPDIR); - if (tmpdir == NULL) - tmpdir = tmp_dir; - bfsz = TMP_FILE_FMT_LEN + strlen(tmpdir) + 10; - bf = AGALOC(bfsz, "tmp fil"); - snprintf(bf, bfsz, TMP_FILE_FMT, tmpdir, my_pid); - } - - { - static mode_t const cmask = S_IRWXO | S_IRWXG; - mode_t svmsk = umask(cmask); - int fd = mkstemp(bf); - (void)umask(svmsk); - - if (fd < 0) { - AGFREE(bf); - return NULL; - } - *buf = bf; - return fdopen(fd, "w"); - } -} - -static inline char * -mk_pager_cmd(char const * fname) -{ - /* - * Page the file and remove it when done. For shell script processing, - * we must redirect the output to the current stderr, otherwise stdout. - */ - fclose(option_usage_fp); - option_usage_fp = NULL; - - { - char const * pager = (char const *)getenv(PAGER_NAME); - size_t bfsz; - char * res; - - /* - * Use the "more(1)" program if "PAGER" has not been defined - */ - if (pager == NULL) - pager = MORE_STR; - - bfsz = 2 * strlen(fname) + strlen(pager) + PAGE_USAGE_FMT_LEN; - res = AGALOC(bfsz, "more cmd"); - snprintf(res, bfsz, PAGE_USAGE_FMT, pager, fname); - AGFREE(fname); - return res; - } -} -#endif - -/*=export_func optionPagedUsage - * private: - * - * what: emit help text and pass through a pager program. - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Run the usage output through a pager. - * This is very handy if it is very long. - * This is disabled on platforms without a working fork() function. -=*/ -void -optionPagedUsage(tOptions * opts, tOptDesc * od) -{ -#if ! defined(HAVE_WORKING_FORK) - if ((od->fOptState & OPTST_RESET) != 0) - return; - - (*opts->pUsageProc)(opts, EXIT_SUCCESS); -#else - static bool sv_print_exit = false; - static char * fil_name = NULL; - - /* - * IF we are being called after the usage proc is done - * (and thus has called "exit(2)") - * THEN invoke the pager to page through the usage file we created. - */ - switch (pagerState) { - case PAGER_STATE_INITIAL: - { - if ((od->fOptState & OPTST_RESET) != 0) - return; - option_usage_fp = open_tmp_usage(&fil_name); - if (option_usage_fp == NULL) - (*opts->pUsageProc)(opts, EXIT_SUCCESS); - - pagerState = PAGER_STATE_READY; - sv_print_exit = print_exit; - - /* - * Set up so this routine gets called during the exit logic - */ - atexit((void(*)(void))optionPagedUsage); - - /* - * The usage procedure will now put the usage information into - * the temporary file we created above. Keep any shell commands - * out of the result. - */ - print_exit = false; - (*opts->pUsageProc)(opts, EXIT_SUCCESS); - - /* NOTREACHED */ - _exit(EXIT_FAILURE); - } - - case PAGER_STATE_READY: - fil_name = mk_pager_cmd(fil_name); - - if (sv_print_exit) { - fputs("\nexit 0\n", stdout); - fclose(stdout); - dup2(STDERR_FILENO, STDOUT_FILENO); - - } else { - fclose(stderr); - dup2(STDOUT_FILENO, STDERR_FILENO); - } - - ignore_val( system( fil_name)); - AGFREE(fil_name); - - case PAGER_STATE_CHILD: - /* - * This is a child process used in creating shell script usage. - */ - break; - } -#endif -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/pgusage.c */ diff --git a/src/libopts/proto.h b/src/libopts/proto.h deleted file mode 100644 index 437e81e..0000000 --- a/src/libopts/proto.h +++ /dev/null @@ -1,620 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * Prototypes for autoopts - * Generated Sun Aug 26 10:44:39 PDT 2018 - */ -#ifndef AUTOOPTS_PROTO_H_GUARD -#define AUTOOPTS_PROTO_H_GUARD 1 - - -/* - * Static declarations from alias.c - */ -static tSuccess -too_many_occurrences(tOptions * opts, tOptDesc * od); - -/* - * Static declarations from autoopts.c - */ -static void * -ao_malloc(size_t sz); - -static void * -ao_realloc(void *p, size_t sz); - -static char * -ao_strdup(char const *str); - -static tSuccess -handle_opt(tOptions * opts, tOptState * o_st); - -static tSuccess -next_opt(tOptions * opts, tOptState * o_st); - -static tSuccess -regular_opts(tOptions * opts); - -/* - * Static declarations from check.c - */ -static bool -has_conflict(tOptions * pOpts, tOptDesc * od); - -static bool -occurs_enough(tOptions * pOpts, tOptDesc * pOD); - -static bool -is_consistent(tOptions * pOpts); - -/* - * Static declarations from configfile.c - */ -static void -file_preset(tOptions * opts, char const * fname, int dir); - -static char * -handle_comment(char * txt); - -static char * -handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir); - -static char * -handle_directive(tOptions * opts, char * txt); - -static char * -aoflags_directive(tOptions * opts, char * txt); - -static char * -program_directive(tOptions * opts, char * txt); - -static char * -handle_section(tOptions * opts, char * txt); - -static int -parse_xml_encoding(char ** ppz); - -static char * -trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode); - -static void -cook_xml_text(char * pzData); - -static char * -handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir); - -static void -intern_file_load(tOptions * opts); - -static char const * -parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, - tOptionValue * pType); - -static char const * -parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ); - -static char const * -parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ); - -static char const * -parse_value(char const * txt, tOptionValue * typ); - -/* - * Static declarations from cook.c - */ -static char * -nl_count(char * start, char * end, int * lnct_p); - -static bool -contiguous_quote(char ** pps, char * pq, int * lnct_p); - -/* - * Static declarations from enum.c - */ -static void -enum_err(tOptions * pOpts, tOptDesc * pOD, - char const * const * paz_names, int name_ct); - -static uintptr_t -find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, - char const * const * paz_names, unsigned int name_ct); - -static void -set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, - unsigned int name_ct); - -static void -set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, - unsigned int nm_ct); - -static uintptr_t -check_membership_start(tOptDesc * od, char const ** argp, bool * invert); - -static uintptr_t -find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, - char const * const * nm_list, unsigned int nm_ct); - -/* - * Static declarations from env.c - */ -static void -doPrognameEnv(tOptions * pOpts, teEnvPresetType type); - -static void -do_env_opt(tOptState * os, char * env_name, - tOptions * pOpts, teEnvPresetType type); - -static void -env_presets(tOptions * pOpts, teEnvPresetType type); - -/* - * Static declarations from file.c - */ -static void -check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD); - -static void -open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); - -static void -fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); - -/* - * Static declarations from find.c - */ -static int -parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz); - -static void -opt_ambiguities(tOptions * opts, char const * name, int nm_len); - -static int -opt_match_ct(tOptions * opts, char const * name, int nm_len, - int * ixp, bool * disable); - -static tSuccess -opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st); - -static tSuccess -opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st); - -static tSuccess -opt_ambiguous(tOptions * opts, char const * name, int match_ct); - -static tSuccess -opt_find_long(tOptions * opts, char const * opt_name, tOptState * state); - -static tSuccess -opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState); - -static tSuccess -get_opt_arg_must(tOptions * opts, tOptState * o_st); - -static tSuccess -get_opt_arg_may(tOptions * pOpts, tOptState * o_st); - -static tSuccess -get_opt_arg_none(tOptions * pOpts, tOptState * o_st); - -static tSuccess -get_opt_arg(tOptions * opts, tOptState * o_st); - -static tSuccess -find_opt(tOptions * opts, tOptState * o_st); - -/* - * Static declarations from init.c - */ -static tSuccess -validate_struct(tOptions * opts, char const * pname); - -static tSuccess -immediate_opts(tOptions * opts); - -static tSuccess -do_presets(tOptions * opts); - -static bool -ao_initialize(tOptions * opts, int a_ct, char ** a_v); - -/* - * Static declarations from load.c - */ -static bool -get_realpath(char * buf, size_t b_sz); - -static bool -add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path); - -static bool -add_env_val(char * buf, int buf_sz, char const * name); - -static void -munge_str(char * txt, tOptionLoadMode mode); - -static char * -assemble_arg_val(char * txt, tOptionLoadMode mode); - -static char * -trim_quotes(char * arg); - -static bool -direction_ok(opt_state_mask_t f, int dir); - -static void -load_opt_line(tOptions * opts, tOptState * opt_state, char * line, - tDirection direction, tOptionLoadMode load_mode ); - -/* - * Static declarations from makeshell.c - */ -noreturn static void -option_exits(int exit_code); - -noreturn static void -ao_bug(char const * msg); - -static void -fserr_warn(char const * prog, char const * op, char const * fname); - -noreturn static void -fserr_exit(char const * prog, char const * op, char const * fname); - -static void -emit_var_text(char const * prog, char const * var, int fdin); - -static void -text_to_var(tOptions * opts, teTextTo which, tOptDesc * od); - -static void -emit_usage(tOptions * opts); - -static void -emit_wrapup(tOptions * opts); - -static void -emit_setup(tOptions * opts); - -static void -emit_action(tOptions * opts, tOptDesc * od); - -static void -emit_inaction(tOptions * opts, tOptDesc * od); - -static void -emit_flag(tOptions * opts); - -static void -emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts); - -static void -emit_long(tOptions * opts); - -static char * -load_old_output(char const * fname, char const * pname); - -static void -open_out(char const * fname, char const * pname); - -/* - * Static declarations from nested.c - */ -static void -remove_continuation(char * src); - -static char const * -scan_q_str(char const * pzTxt); - -static tOptionValue * -add_string(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len); - -static tOptionValue * -add_bool(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len); - -static tOptionValue * -add_number(void ** pp, char const * name, size_t nm_len, - char const * val, size_t d_len); - -static tOptionValue * -add_nested(void ** pp, char const * name, size_t nm_len, - char * val, size_t d_len); - -static char const * -scan_name(char const * name, tOptionValue * res); - -static char const * -unnamed_xml(char const * txt); - -static char const * -scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val); - -static char const * -find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len); - -static char const * -scan_xml(char const * xml_name, tOptionValue * res_val); - -static void -unload_arg_list(tArgList * arg_list); - -static void -sort_list(tArgList * arg_list); - -static tOptionValue * -optionLoadNested(char const * text, char const * name, size_t nm_len); - -static int -get_special_char(char const ** ppz, int * ct); - -static void -emit_special_char(FILE * fp, int ch); - -/* - * Static declarations from parse-duration.c - */ -static unsigned long -str_const_to_ul (cch_t * str, cch_t ** ppz, int base); - -static long -str_const_to_l (cch_t * str, cch_t ** ppz, int base); - -static time_t -scale_n_add (time_t base, time_t val, int scale); - -static time_t -parse_hr_min_sec (time_t start, cch_t * pz); - -static time_t -parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale); - -static time_t -parse_year_month_day (cch_t * pz, cch_t * ps); - -static time_t -parse_yearmonthday (cch_t * in_pz); - -static time_t -parse_YMWD (cch_t * pz); - -static time_t -parse_hour_minute_second (cch_t * pz, cch_t * ps); - -static time_t -parse_hourminutesecond (cch_t * in_pz); - -static time_t -parse_HMS (cch_t * pz); - -static time_t -parse_time (cch_t * pz); - -static char * -trim (char * pz); - -static time_t -parse_period (cch_t * in_pz); - -static time_t -parse_non_iso8601 (cch_t * pz); - -/* - * Static declarations from pgusage.c - */ -static inline FILE * -open_tmp_usage(char ** buf); - -static inline char * -mk_pager_cmd(char const * fname); - -/* - * Static declarations from putshell.c - */ -static size_t -string_size(char const * scan, size_t nl_len); - -static char const * -print_quoted_apostrophes(char const * str); - -static void -print_quot_str(char const * str); - -static void -print_enumeration(tOptions * pOpts, tOptDesc * pOD); - -static void -print_membership(tOptions * pOpts, tOptDesc * pOD); - -static void -print_stacked_arg(tOptions * pOpts, tOptDesc * pOD); - -static void -print_reordering(tOptions * opts); - -/* - * Static declarations from reset.c - */ -static void -optionReset(tOptions * pOpts, tOptDesc * pOD); - -static void -optionResetEverything(tOptions * pOpts); - -/* - * Static declarations from restore.c - */ -static void -fixupSavedOptionArgs(tOptions * pOpts); - -/* - * Static declarations from save.c - */ -static char const * -find_dir_name(tOptions * opts, int * p_free); - -static char const * -find_file_name(tOptions * opts, int * p_free_name); - -static void -prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl); - -static void -prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp); - -static void -prt_string(FILE * fp, char const * name, char const * pz); - -static void -prt_val_list(FILE * fp, char const * name, tArgList * al); - -static void -prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); - -static void -remove_settings(tOptions * opts, char const * fname); - -static FILE * -open_sv_file(tOptions * opts, save_flags_mask_t save_fl); - -static void -prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl); - -static void -prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); - -static void -prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); - -static void -prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); - -static void -prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl); - -/* - * Static declarations from sort.c - */ -static tSuccess -must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx); - -static tSuccess -maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx); - -static tSuccess -short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx); - -static void -optionSort(tOptions * opts); - -/* - * Static declarations from stack.c - */ -static void -addArgListEntry(void ** ppAL, void * entry); - -/* - * Static declarations from text_mmap.c - */ -static void -load_text_file(tmap_info_t * mapinfo, char const * pzFile); - -static void -validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo); - -static void -close_mmap_files(tmap_info_t * mi); - -/* - * Static declarations from tokenize.c - */ -static void -copy_cooked(ch_t ** ppDest, char const ** ppSrc); - -static void -copy_raw(ch_t ** ppDest, char const ** ppSrc); - -static token_list_t * -alloc_token_list(char const * str); - -/* - * Static declarations from usage.c - */ -static unsigned int -parse_usage_flags(ao_flag_names_t const * fnt, char const * txt); - -static void -set_usage_flags(tOptions * opts, char const * flg_txt); - -static inline bool -do_gnu_usage(tOptions * pOpts); - -static inline bool -skip_misuse_usage(tOptions * pOpts); - -static void -print_offer_usage(tOptions * opts); - -static void -print_usage_details(tOptions * opts, int exit_code); - -static void -print_one_paragraph(char const * text, bool plain, FILE * fp); - -static void -prt_conflicts(tOptions * opts, tOptDesc * od); - -static void -prt_one_vendor(tOptions * opts, tOptDesc * od, - arg_types_t * argtp, char const * usefmt); - -static void -prt_vendor_opts(tOptions * opts, char const * title); - -static void -prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title); - -static void -prt_ini_list(char const * const * papz, char const * ini_file, - char const * path_nm); - -static void -prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at); - -static void -prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at); - -static void -prt_opt_usage(tOptions * opts, int ex_code, char const * title); - -static void -prt_prog_detail(tOptions * opts); - -static int -setGnuOptFmts(tOptions * opts, char const ** ptxt); - -static int -setStdOptFmts(tOptions * opts, char const ** ptxt); - -/* - * Static declarations from version.c - */ -static void -emit_first_line( - FILE * fp, char const * alt1, char const * alt2, char const * alt3); - -static void -emit_simple_ver(tOptions * o, FILE * fp); - -static void -emit_copy_full(tOptions * o, FILE * fp); - -static void -emit_copy_note(tOptions * opts, FILE * fp); - -static void -print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit); - -#endif /* AUTOOPTS_PROTO_H_GUARD */ diff --git a/src/libopts/putshell.c b/src/libopts/putshell.c deleted file mode 100644 index 84463dd..0000000 --- a/src/libopts/putshell.c +++ /dev/null @@ -1,495 +0,0 @@ - -/** - * \file putshell.c - * - * This module will interpret the options set in the tOptions - * structure and print them to standard out in a fashion that - * will allow them to be interpreted by the Bourne or Korn shells. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/** - * Count the number of bytes required to represent a string as a - * compilable string. - * - * @param[in] scan the text to be rewritten as a C program text string. - * @param[in] nl_len the number of bytes used for each embedded newline. - * - * @returns the count, including the terminating NUL byte. - */ -static size_t -string_size(char const * scan, size_t nl_len) -{ - /* - * Start by counting the start and end quotes, plus the NUL. - */ - size_t res_ln = 3; - - for (;;) { - char ch = *(scan++); - if ((ch >= ' ') && (ch <= '~')) { - - /* - * a backslash allowance for double quotes and baskslashes - */ - res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1; - } - - /* - * When not a normal character, then count the characters - * required to represent whatever it is. - */ - else switch (ch) { - case NUL: - return res_ln; - - case NL: - res_ln += nl_len; - break; - - case HT: - case BEL: - case BS: - case FF: - case CR: - case VT: - res_ln += 2; - break; - - default: - res_ln += 4; /* text len for \xNN */ - } - } -} - -/*=export_func optionQuoteString - * private: - * - * what: Print a string as quoted text suitable for a C compiler. - * arg: + char const * + text + a block of text to quote + - * arg: + char const * + nl + line splice text + - * - * ret_type: char const * - * ret_desc: the allocated input string as a quoted string - * - * doc: - * This is for internal use by autogen and autoopts. - * It takes an input string and produces text the C compiler can process - * to produce an exact copy of the original string. - * The caller must deallocate the result. Standard C strings and - * K&R strings are distinguished by the "nl" string. -=*/ -char const * -optionQuoteString(char const * text, char const * nl) -{ - size_t nl_len = strlen(nl); - size_t out_sz = string_size(text, nl_len); - char * out; - char * res = out = AGALOC(out_sz, "quot str"); - - *(out++) = '"'; - - for (;;) { - unsigned char ch = (unsigned char)*text; - if ((ch >= ' ') && (ch <= '~')) { - if ((ch == '"') || (ch == '\\')) - /* - * We must escape these characters in the output string - */ - *(out++) = '\\'; - *(out++) = (char)ch; - - } else switch (ch) { -# define add_esc_ch(_ch) { *(out++) = '\\'; *(out++) = (_ch); } - case BEL: add_esc_ch('a'); break; - case BS: add_esc_ch('b'); break; - case HT: add_esc_ch('t'); break; - case VT: add_esc_ch('v'); break; - case FF: add_esc_ch('f'); break; - case CR: add_esc_ch('r'); break; - - case LF: - /* - * Place contiguous new-lines on a single line. - * The current character is a NL, check the next one. - */ - while (*++text == NL) - add_esc_ch('n'); - - /* - * Insert a splice before starting next line - */ - if (*text != NUL) { - memcpy(out, nl, nl_len); - out += nl_len; - - continue; /* text is already at the next character */ - } - - add_esc_ch('n'); - /* FALLTHROUGH */ - - case NUL: - /* - * End of string. Terminate the quoted output. If necessary, - * deallocate the text string. Return the scan resumption point. - */ - *(out++) = '"'; - *(out++) = NUL; -#ifndef NDEBUG - if ((size_t)(out - res) > out_sz) { - fputs(misguess_len, stderr); - option_exits(EXIT_FAILURE); - } -#endif - return res; - - default: - /* - * sprintf is safe here, because we already computed - * the amount of space we will be using. Assertion is above. - */ - out += sprintf(out, MK_STR_OCT_FMT, ch); - } - - text++; -# undef add_esc_ch - } -} - -/** - * Print out escaped apostorophes. - * - * @param[in] str the apostrophies to print - */ -static char const * -print_quoted_apostrophes(char const * str) -{ - while (*str == APOSTROPHE) { - fputs(QUOT_APOS, stdout); - str++; - } - return str; -} - -/** - * Print a single quote (apostrophe quoted) string. - * Other than somersaults for apostrophes, nothing else needs quoting. - * - * @param[in] str the string to print - */ -static void -print_quot_str(char const * str) -{ - /* - * Handle empty strings to make the rest of the logic simpler. - */ - if ((str == NULL) || (*str == NUL)) { - fputs(EMPTY_ARG, stdout); - return; - } - - /* - * Emit any single quotes/apostrophes at the start of the string and - * bail if that is all we need to do. - */ - str = print_quoted_apostrophes(str); - if (*str == NUL) - return; - - /* - * Start the single quote string - */ - fputc(APOSTROPHE, stdout); - for (;;) { - char const * pz = strchr(str, APOSTROPHE); - if (pz == NULL) - break; - - /* - * Emit the string up to the single quote (apostrophe) we just found. - */ - (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout); - - /* - * Close the current string, emit the apostrophes and re-open the - * string (IFF there is more text to print). - */ - fputc(APOSTROPHE, stdout); - str = print_quoted_apostrophes(pz); - if (*str == NUL) - return; - - fputc(APOSTROPHE, stdout); - } - - /* - * If we broke out of the loop, we must still emit the remaining text - * and then close the single quote string. - */ - fputs(str, stdout); - fputc(APOSTROPHE, stdout); -} - -static void -print_enumeration(tOptions * pOpts, tOptDesc * pOD) -{ - uintptr_t e_val = pOD->optArg.argEnum; - printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); - - /* - * Convert value to string, print that and restore numeric value. - */ - (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); - printf(QUOT_ARG_FMT, pOD->optArg.argString); - if (pOD->fOptState & OPTST_ALLOC_ARG) - AGFREE(pOD->optArg.argString); - pOD->optArg.argEnum = e_val; - - printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); -} - -static void -print_membership(tOptions * pOpts, tOptDesc * pOD) -{ - char const * svstr = pOD->optArg.argString; - char const * pz; - uintptr_t val = 1; - printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, - (int)(uintptr_t)(pOD->optCookie)); - pOD->optCookie = VOIDP(~0UL); - (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); - - pz = pOD->optArg.argString; - while (*pz != NUL) { - printf("readonly %s_", pOD->pz_NAME); - pz = SPN_PLUS_N_SPACE_CHARS(pz); - - for (;;) { - int ch = *(pz++); - if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout); - else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout); - else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done; - else if (ch == NUL) { pz--; goto name_done; } - else fputc('_', stdout); - } name_done:; - printf(SHOW_VAL_FMT, (unsigned long)val); - val <<= 1; - } - - AGFREE(pOD->optArg.argString); - pOD->optArg.argString = svstr; -} - -static void -print_stacked_arg(tOptions * pOpts, tOptDesc * pOD) -{ - tArgList * pAL = (tArgList *)pOD->optCookie; - char const ** ppz = pAL->apzArgs; - int ct = pAL->useCt; - - printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct); - - while (--ct >= 0) { - printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, - pAL->useCt - ct); - print_quot_str(*(ppz++)); - printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, - pAL->useCt - ct); - } -} - -/** - * emit the arguments as readily parsed text. - * The program options are set by emitting the shell "set" command. - * - * @param[in] opts the program options structure - */ -static void -print_reordering(tOptions * opts) -{ - unsigned int ix; - - fputs(set_dash, stdout); - - for (ix = opts->curOptIdx; - ix < opts->origArgCt; - ix++) { - fputc(' ', stdout); - print_quot_str(opts->origArgVect[ ix ]); - } - fputs(init_optct, stdout); -} - -/*=export_func optionPutShell - * what: write a portable shell script to parse options - * private: - * arg: tOptions *, pOpts, the program options descriptor - * doc: This routine will emit portable shell script text for parsing - * the options described in the option definitions. -=*/ -void -optionPutShell(tOptions * pOpts) -{ - int optIx = 0; - - printf(zOptCtFmt, pOpts->curOptIdx-1); - - do { - tOptDesc * pOD = pOpts->pOptDesc + optIx; - - if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0) - continue; - - /* - * Equivalence classes are hard to deal with. Where the - * option data wind up kind of squishes around. For the purposes - * of emitting shell state, they are not recommended, but we'll - * do something. I guess we'll emit the equivalenced-to option - * at the point in time when the base option is found. - */ - if (pOD->optEquivIndex != NO_EQUIVALENT) - continue; /* equivalence to a different option */ - - /* - * Equivalenced to a different option. Process the current option - * as the equivalenced-to option. Keep the persistent state bits, - * but copy over the set-state bits. - */ - if (pOD->optActualIndex != optIx) { - tOptDesc * p = pOpts->pOptDesc + pOD->optActualIndex; - p->optArg = pOD->optArg; - p->fOptState &= OPTST_PERSISTENT_MASK; - p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK; - printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME); - pOD = p; - } - - /* - * If the argument type is a set membership bitmask, then we always - * emit the thing. We do this because it will always have some sort - * of bitmask value and we need to emit the bit values. - */ - if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { - print_membership(pOpts, pOD); - continue; - } - - /* - * IF the option was either specified or it wakes up enabled, - * then we will emit information. Otherwise, skip it. - * The idea is that if someone defines an option to initialize - * enabled, we should tell our shell script that it is enabled. - */ - if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD)) - continue; - - /* - * Handle stacked arguments - */ - if ( (pOD->fOptState & OPTST_STACKED) - && (pOD->optCookie != NULL) ) { - print_stacked_arg(pOpts, pOD); - continue; - } - - /* - * If the argument has been disabled, - * Then set its value to the disablement string - */ - if ((pOD->fOptState & OPTST_DISABLED) != 0) { - printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME, - (pOD->pz_DisablePfx != NULL) - ? pOD->pz_DisablePfx : "false"); - continue; - } - - /* - * If the argument type is numeric, the last arg pointer - * is really the VALUE of the string that was pointed to. - */ - if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) { - printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, - (int)pOD->optArg.argInt); - continue; - } - - /* - * If the argument type is an enumeration, then it is much - * like a text value, except we call the callback function - * to emit the value corresponding to the "optArg" number. - */ - if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) { - print_enumeration(pOpts, pOD); - continue; - } - - /* - * If the argument type is numeric, the last arg pointer - * is really the VALUE of the string that was pointed to. - */ - if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) { - printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME, - (pOD->optArg.argBool == 0) ? "false" : "true"); - continue; - } - - /* - * IF the option has an empty value, - * THEN we set the argument to the occurrence count. - */ - if ( (pOD->optArg.argString == NULL) - || (pOD->optArg.argString[0] == NUL) ) { - - printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, - pOD->optOccCt); - continue; - } - - /* - * This option has a text value - */ - printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); - print_quot_str(pOD->optArg.argString); - printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); - - } while (++optIx < pOpts->presetOptCt ); - - if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0) - && (pOpts->curOptIdx < pOpts->origArgCt)) - print_reordering(pOpts); - - fflush(stdout); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/putshell.c */ diff --git a/src/libopts/reset.c b/src/libopts/reset.c deleted file mode 100644 index f7b58e8..0000000 --- a/src/libopts/reset.c +++ /dev/null @@ -1,141 +0,0 @@ - -/** - * \file reset.c - * - * Reset the option state to the compiled state. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -static void -optionReset(tOptions * pOpts, tOptDesc * pOD) -{ - pOD->fOptState &= OPTST_PERSISTENT_MASK; - pOD->fOptState |= OPTST_RESET; - if (pOD->pOptProc != NULL) - pOD->pOptProc(pOpts, pOD); - pOD->optArg.argString = - pOpts->originalOptArgArray[ pOD->optIndex ].argString; - pOD->optCookie = pOpts->originalOptArgCookie[ pOD->optIndex ]; - pOD->fOptState &= OPTST_PERSISTENT_MASK; -} - - -static void -optionResetEverything(tOptions * pOpts) -{ - tOptDesc * pOD = pOpts->pOptDesc; - int ct = pOpts->presetOptCt; - - for (;;) { - optionReset(pOpts, pOD); - - if (--ct <= 0) - break; - pOD++; - } -} - - -/*=export_func optionResetOpt - * private: - * - * what: Reset the value of an option - * arg: + tOptions * + pOpts + program options descriptor + - * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + - * - * doc: - * This code will cause another option to be reset to its initial state. - * For example, --reset=foo will cause the --foo option to be reset. -=*/ -void -optionResetOpt(tOptions * pOpts, tOptDesc * pOD) -{ - static bool reset_active = false; - - tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED); - char const * pzArg = pOD->optArg.argString; - tSuccess succ; - - if (pOpts <= OPTPROC_EMIT_LIMIT) - return; - - if (reset_active) - return; - - if ( (! HAS_originalOptArgArray(pOpts)) - || (pOpts->originalOptArgCookie == NULL)) - ao_bug(zno_reset); - - if ((pzArg == NULL) || (*pzArg == NUL)) { - fprintf(stderr, zreset_arg, pOpts->pzProgName, pOD->pz_Name); - pOpts->pUsageProc(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - assert(0 == 1); - } - - reset_active = true; - - if (pzArg[1] == NUL) { - if (*pzArg == '*') { - optionResetEverything(pOpts); - reset_active = false; - return; - } - - succ = opt_find_short(pOpts, (uint8_t)*pzArg, &opt_state); - if (! SUCCESSFUL(succ)) { - fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg); - pOpts->pUsageProc(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - assert(0 == 1); - } - } else { - succ = opt_find_long(pOpts, (char *)pzArg, &opt_state); - if (! SUCCESSFUL(succ)) { - fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg); - pOpts->pUsageProc(pOpts, EXIT_FAILURE); - /* NOTREACHED */ - assert(0 == 1); - } - } - - /* - * We've found the indicated option. Turn off all non-persistent - * flags because we're forcing the option back to its initialized state. - * Call any callout procedure to handle whatever it needs to. - * Finally, clear the reset flag, too. - */ - optionReset(pOpts, opt_state.pOD); - reset_active = false; -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/reset.c */ diff --git a/src/libopts/restore.c b/src/libopts/restore.c deleted file mode 100644 index 36ebbce..0000000 --- a/src/libopts/restore.c +++ /dev/null @@ -1,223 +0,0 @@ - -/* - * \file restore.c - * - * This module's routines will save the current option state to memory - * and restore it. If saved prior to the initial optionProcess call, - * then the initial state will be restored. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/* - * optionFixupSavedOpts Really, it just wipes out option state for - * options that are troublesome to copy. viz., stacked strings and - * hierarcicaly valued option args. We do duplicate string args that - * have been marked as allocated though. - */ -static void -fixupSavedOptionArgs(tOptions * pOpts) -{ - tOptions * p = pOpts->pSavedState; - tOptDesc * pOD = pOpts->pOptDesc; - int ct = pOpts->optCt; - - /* - * Make sure that allocated stuff is only referenced in the - * archived copy of the data. - */ - for (; ct-- > 0; pOD++) { - switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { - case OPARG_TYPE_STRING: - if (pOD->fOptState & OPTST_STACKED) { - tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); - q->optCookie = NULL; - } - if (pOD->fOptState & OPTST_ALLOC_ARG) { - tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); - AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg"); - } - break; - - case OPARG_TYPE_HIERARCHY: - { - tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); - q->optCookie = NULL; - } - } - } -} - -/*=export_func optionSaveState - * - * what: saves the option state to memory - * arg: tOptions *, pOpts, program options descriptor - * - * doc: - * - * This routine will allocate enough memory to save the current option - * processing state. If this routine has been called before, that memory - * will be reused. You may only save one copy of the option state. This - * routine may be called before optionProcess(3AO). If you do call it - * before the first call to optionProcess, then you may also change the - * contents of argc/argv after you call optionRestore(3AO) - * - * In fact, more strongly put: it is safest to only use this function - * before having processed any options. In particular, the saving and - * restoring of stacked string arguments and hierarchical values is - * disabled. The values are not saved. - * - * err: If it fails to allocate the memory, - * it will print a message to stderr and exit. - * Otherwise, it will always succeed. -=*/ -void -optionSaveState(tOptions * pOpts) -{ - tOptions * p = (tOptions *)pOpts->pSavedState; - - if (p == NULL) { - size_t sz = sizeof(*pOpts) - + ((size_t)pOpts->optCt * sizeof(tOptDesc)); - p = AGALOC(sz, "saved option state"); - - pOpts->pSavedState = p; - } - - memcpy(p, pOpts, sizeof(*p)); - memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc)); - - fixupSavedOptionArgs(pOpts); -} - - -/*=export_func optionRestore - * - * what: restore option state from memory copy - * arg: tOptions *, pOpts, program options descriptor - * - * doc: Copy back the option state from saved memory. - * The allocated memory is left intact, so this routine can be - * called repeatedly without having to call optionSaveState again. - * If you are restoring a state that was saved before the first call - * to optionProcess(3AO), then you may change the contents of the - * argc/argv parameters to optionProcess. - * - * err: If you have not called @code{optionSaveState} before, a diagnostic is - * printed to @code{stderr} and exit is called. -=*/ -void -optionRestore(tOptions * pOpts) -{ - tOptions * p = (tOptions *)pOpts->pSavedState; - - if (p == NULL) { - char const * pzName = pOpts->pzProgName; - if (pzName == NULL) { - pzName = pOpts->pzPROGNAME; - if (pzName == NULL) - pzName = zNil; - } - fprintf(stderr, zNoState, pzName); - option_exits(EXIT_FAILURE); - } - - pOpts->pSavedState = NULL; - optionFree(pOpts); - - memcpy(pOpts, p, sizeof(*p)); - memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); - pOpts->pSavedState = p; - - fixupSavedOptionArgs(pOpts); -} - -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ - -/*=export_func optionFree - * - * what: free allocated option processing memory - * arg: tOptions *, pOpts, program options descriptor - * - * doc: AutoOpts sometimes allocates memory and puts pointers to it in the - * option state structures. This routine deallocates all such memory. - * - * err: As long as memory has not been corrupted, - * this routine is always successful. -=*/ -void -optionFree(tOptions * pOpts) -{ - free_saved_state: - { - tOptDesc * p = pOpts->pOptDesc; - int ct = pOpts->optCt; - do { - if (p->fOptState & OPTST_ALLOC_ARG) { - AGFREE(p->optArg.argString); - p->optArg.argString = NULL; - p->fOptState &= ~OPTST_ALLOC_ARG; - } - - switch (OPTST_GET_ARGTYPE(p->fOptState)) { - case OPARG_TYPE_STRING: -#ifdef WITH_LIBREGEX - if ( (p->fOptState & OPTST_STACKED) - && (p->optCookie != NULL)) { - p->optArg.argString = ".*"; - optionUnstackArg(pOpts, p); - } -#else - /* leak memory */; -#endif - break; - - case OPARG_TYPE_HIERARCHY: - if (p->optCookie != NULL) - unload_arg_list(p->optCookie); - break; - } - - p->optCookie = NULL; - } while (p++, --ct > 0); - } - if (pOpts->pSavedState != NULL) { - tOptions * p = (tOptions *)pOpts->pSavedState; - memcpy(pOpts, p, sizeof(*p)); - memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); - AGFREE(pOpts->pSavedState); - pOpts->pSavedState = NULL; - goto free_saved_state; - } -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/restore.c */ diff --git a/src/libopts/save-flags.c b/src/libopts/save-flags.c deleted file mode 100644 index d295170..0000000 --- a/src/libopts/save-flags.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (save-flags.c) - * - * It has been AutoGen-ed - * From the definitions /tmp/.ag-ufBbQe/save-flags.def - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - */ -#include "save-flags.h" -#include -#ifndef MISSING_INTTYPES_H -# include -#endif - -typedef enum { - SVFL_BNM_DEFAULT = 0, - SVFL_BNM_USAGE = 1, - SVFL_BNM_UPDATE = 2, - SVFL_COUNT_BNM -} save_flags_enum_t; - -static save_flags_enum_t -find_save_flags_bnm(char const * str, size_t len); - - -#include -#include -#ifndef NUL -#define NUL '\0' -#endif - -/* ANSI-C code produced by gperf version 3.1 */ -/* Command-line: gperf save-flags.gp */ -/* Computed positions: -k'' */ - - -# if 0 /* gperf build options: */ -// %struct-type -// %language=ANSI-C -// %includes -// %global-table -// %omit-struct-type -// %readonly-tables -// %compare-strncmp -// -// %define slot-name svfl_name -// %define hash-function-name save_flags_hash -// %define lookup-function-name find_save_flags_name -// %define word-array-name save_flags_table -// %define initializer-suffix ,SVFL_COUNT_BNM -// -# endif - -#include "save-flags.h" -typedef struct { - char const * svfl_name; - save_flags_enum_t svfl_id; -} save_flags_map_t; -#include - -/* maximum key range = 3, duplicates = 0 */ - -static unsigned int -save_flags_hash (register const char *str, register size_t len) -{ - (void)str; - (void)len; - return len; -} - -static const save_flags_map_t save_flags_table[] = - { - {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, - {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, - {"",SVFL_COUNT_BNM}, - {"usage", SVFL_BNM_USAGE}, - {"update", SVFL_BNM_UPDATE}, - {"default", SVFL_BNM_DEFAULT} - }; - -static inline const save_flags_map_t * -find_save_flags_name (register const char *str, register size_t len) -{ - if (len <= 7 && len >= 5) - { - register unsigned int key = (int)save_flags_hash (str, len); - - if (key <= 7) - { - register const char *s = save_flags_table[key].svfl_name; - - if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') - return &save_flags_table[key]; - } - } - return 0; -} - -/** - * Convert a command (keyword) to a save_flags_enum_t enumeration value. - * - * @param[in] str a string that should start with a known key word. - * @param[in] len the provided length of the keyword at \a str. - * @returns the enumeration value. - * If not found, that value is SVFL_COUNT_BNM. - */ -static save_flags_enum_t -find_save_flags_bnm(char const * str, size_t len) -{ - save_flags_map_t const * map; - - map = find_save_flags_name(str, (unsigned int)len); - if (map != NULL) - return map->svfl_id; - /* Check for a partial match */ - { - /* - * Indexes of valid save_flags_table entries in sorted order: - */ - static unsigned int const ix_map[] = { - 7, 6, 5 }; - save_flags_enum_t res = SVFL_COUNT_BNM; - static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1; - int lo = 0; - int hi = HI; - int av; - int cmp; - - for (;;) { - av = (hi + lo) / 2; - map = save_flags_table + ix_map[av]; - cmp = strncmp(map->svfl_name, str, len); - if (cmp == 0) break; - if (cmp > 0) - hi = av - 1; - else lo = av + 1; - if (lo > hi) - return SVFL_COUNT_BNM; - } - res = map->svfl_id; - /* - * If we have an exact match, accept it. - */ - if (map->svfl_name[len] == NUL) - return res; - /* - * Check for a duplicate partial match (a partial match - * with a higher or lower index than "av". - */ - if (av < HI) { - map = save_flags_table + ix_map[av + 1]; - if (strncmp(map->svfl_name, str, len) == 0) - return SVFL_COUNT_BNM; - } - if (av > 0) { - map = save_flags_table + ix_map[av - 1]; - if (strncmp(map->svfl_name, str, len) == 0) - return SVFL_COUNT_BNM; - } - return res; - } -} - -/** - * Convert a string to a save_flags_mask_t mask. - * Bit names prefixed with a hyphen have the bit removed from the mask. - * If the string starts with a '-', '+' or '|' character, then - * the old value is used as a base, otherwise the result mask - * is initialized to zero. Separating bit names with '+' or '|' - * characters is optional. By default, the bits are "or"-ed into the - * result. - * - * @param[in] str string with a list of bit names - * @param[in] old previous value, used if \a str starts with a '+' or '-'. - * - * @returns an unsigned integer with the bits set. - */ -save_flags_mask_t -save_flags_str2mask(char const * str, save_flags_mask_t old) -{ - static char const white[] = ", \t\f"; - static char const name_chars[] = - "adefglpstu" - "ADEFGLPSTU"; - - save_flags_mask_t res = 0; - int have_data = 0; - - for (;;) { - save_flags_enum_t val; - unsigned int val_len; - unsigned int invert = 0; - - str += strspn(str, white); - switch (*str) { - case NUL: return res; - case '-': case '~': - invert = 1; - /* FALLTHROUGH */ - - case '+': case '|': - if (have_data == 0) - res = old; - - str += 1 + strspn(str + 1, white); - if (*str == NUL) - return 0; - } - - val_len = strspn(str, name_chars); - if (val_len == 0) - return 0; - val = find_save_flags_bnm(str, val_len); - if (val == SVFL_COUNT_BNM) - return 0; - if (invert) - res &= ~((save_flags_mask_t)1 << val); - else - res |= (save_flags_mask_t)1 << val; - have_data = 1; - str += val_len; - } -} -/* end of save-flags.c */ diff --git a/src/libopts/save-flags.h b/src/libopts/save-flags.h deleted file mode 100644 index dcfe0c9..0000000 --- a/src/libopts/save-flags.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- buffer-read-only: t -*- vi: set ro: - * - * DO NOT EDIT THIS FILE (save-flags.h) - * - * It has been AutoGen-ed - * From the definitions /tmp/.ag-ufBbQe/save-flags.def - * and the template file str2enum - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name ``Bruce Korb'' nor the name of any other - * contributor may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * str2enum IS PROVIDED BY Bruce Korb ``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 Bruce Korb OR ANY OTHER 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. - * - * Command/Keyword Dispatcher - */ -#ifndef STR2ENUM_SAVE_FLAGS_H_GUARD -#define STR2ENUM_SAVE_FLAGS_H_GUARD 1 -#include -#include - -/** integral type for holding save_flags masks */ -typedef uint32_t save_flags_mask_t; - -/** bits defined for save_flags_mask_t */ -/** include default values in commentary */ -#define SVFL_DEFAULT 0x0001U -/** include usage text in commentary */ -#define SVFL_USAGE 0x0002U -/** replace or append state */ -#define SVFL_UPDATE 0x0004U - -/** bits in USAGE_DEFAULT mask: - * usage default */ -#define SVFL_USAGE_DEFAULT_MASK 0x0003U - -/** all bits in save_flags_mask_t masks */ -#define SVFL_MASK_ALL 0x0007U - -/** no bits in save_flags_mask_t */ -#define SVFL_NONE 0x0000U - -/** buffer size needed to hold all bit names for save_flags_mask_t masks */ -#define MAX_SAVE_FLAGS_NAME_SIZE 21 - -extern save_flags_mask_t -save_flags_str2mask(char const * str, save_flags_mask_t old); - -#endif /* STR2ENUM_SAVE_FLAGS_H_GUARD */ -/* end of save-flags.h */ diff --git a/src/libopts/save.c b/src/libopts/save.c deleted file mode 100644 index 8b1fba9..0000000 --- a/src/libopts/save.c +++ /dev/null @@ -1,916 +0,0 @@ - -/* - * \file save.c - * - * This module's routines will take the currently set options and - * store them into an ".rc" file for re-interpretation the next - * time the invoking program is run. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ -#include "save-flags.h" - -/** - * find the config file directory name - * - * @param opts the options descriptor - * @param p_free tell caller if name was allocated or not - */ -static char const * -find_dir_name(tOptions * opts, int * p_free) -{ - char const * dir; - - if ( (opts->specOptIdx.save_opts == NO_EQUIVALENT) - || (opts->specOptIdx.save_opts == 0)) - return NULL; - - dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; - if ((dir != NULL) && (*dir != NUL)) { - char const * pz = strchr(dir, '>'); - if (pz == NULL) - return dir; - while (*(++pz) == '>') ; - pz += strspn(pz, " \t"); - dir = pz; - if (*dir != NUL) - return dir; - } - - if (opts->papzHomeList == NULL) - return NULL; - - /* - * This function only works if there is a directory where - * we can stash the RC (INI) file. - */ - for (int idx = 0;; idx++) { - char f_name[ AG_PATH_MAX+1 ]; - - dir = opts->papzHomeList[idx]; - - switch (*dir) { - case '$': - break; - case NUL: - continue; - default: - return dir; - } - if (optionMakePath(f_name, (int)sizeof(f_name), dir, opts->pzProgPath)) { - *p_free = true; - AGDUPSTR(dir, f_name, "homerc"); - return dir; - } - } - return NULL; -} - -/** - * Find the name of the save-the-options file - * - * @param opts the options descriptor - * @param p_free_name tell caller if name was allocated or not - */ -static char const * -find_file_name(tOptions * opts, int * p_free_name) -{ - struct stat stBuf; - int free_dir_name = 0; - - char const * res = find_dir_name(opts, &free_dir_name); - if (res == NULL) - return res; - - /* - * See if we can find the specified directory. We use a once-only loop - * structure so we can bail out early. - */ - if (stat(res, &stBuf) != 0) do { - char z[AG_PATH_MAX]; - char * dirchp; - - /* - * IF we could not, check to see if we got a full - * path to a file name that has not been created yet. - */ - if (errno != ENOENT) { - bogus_name: - fprintf(stderr, zsave_warn, opts->pzProgName, res); - fprintf(stderr, zNoStat, errno, strerror(errno), res); - if (free_dir_name) - AGFREE(res); - return NULL; - } - - /* - * Strip off the last component, stat the remaining string and - * that string must name a directory - */ - dirchp = strrchr(res, DIRCH); - if (dirchp == NULL) { - stBuf.st_mode = S_IFREG; - break; /* found directory -- viz., "." */ - } - - if ((size_t)(dirchp - res) >= sizeof(z)) - goto bogus_name; - - memcpy(z, res, (size_t)(dirchp - res)); - z[dirchp - res] = NUL; - - if ((stat(z, &stBuf) != 0) || ! S_ISDIR(stBuf.st_mode)) - goto bogus_name; - stBuf.st_mode = S_IFREG; /* file within this directory */ - } while (false); - - /* - * IF what we found was a directory, - * THEN tack on the config file name - */ - if (S_ISDIR(stBuf.st_mode)) { - - { - size_t sz = strlen(res) + strlen(opts->pzRcName) + 2; - char * pzPath = (char *)AGALOC(sz, "file name"); - if ( snprintf(pzPath, sz, "%s/%s", res, opts->pzRcName) - >= (int)sz) - option_exits(EXIT_FAILURE); - - if (free_dir_name) - AGFREE(res); - res = pzPath; - free_dir_name = 1; - } - - /* - * IF we cannot stat the object for any reason other than - * it does not exist, then we bail out - */ - if (stat(res, &stBuf) != 0) { - if (errno != ENOENT) { - fprintf(stderr, zsave_warn, opts->pzProgName, res); - fprintf(stderr, zNoStat, errno, strerror(errno), - res); - AGFREE(res); - return NULL; - } - - /* - * It does not exist yet, but it will be a regular file - */ - stBuf.st_mode = S_IFREG; - } - } - - /* - * Make sure that whatever we ultimately found, that it either is - * or will soon be a file. - */ - if (! S_ISREG(stBuf.st_mode)) { - fprintf(stderr, zsave_warn, opts->pzProgName, res); - if (free_dir_name) - AGFREE(res); - return NULL; - } - - /* - * Get rid of the old file - */ - *p_free_name = free_dir_name; - return res; -} - -/** - * print one option entry to the save file. - * - * @param[in] fp the file pointer for the save file - * @param[in] od the option descriptor to print - * @param[in] l_arg the last argument for the option - * @param[in] save_fl include usage in comments - */ -static void -prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl) -{ - int space_ct; - - if (save_fl & SVFL_USAGE) - fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); - if (UNUSED_OPT(od) && (save_fl & SVFL_DEFAULT)) - fputs(ao_default_use, fp); - - /* - * There is an argument. Pad the name so values line up. - * Not disabled *OR* this got equivalenced to another opt, - * then use current option name. - * Otherwise, there must be a disablement name. - */ - { - char const * pz = - (od->pz_DisableName == NULL) - ? od->pz_Name - : (DISABLED_OPT(od) - ? od->pz_DisableName - : ((od->optEquivIndex == NO_EQUIVALENT) - ? od->pz_Name : od->pz_DisableName) - ); - - space_ct = 17 - strlen(pz); - fputs(pz, fp); - } - - if ( (l_arg == NULL) - && (OPTST_GET_ARGTYPE(od->fOptState) != OPARG_TYPE_NUMERIC)) - goto end_entry; - - fputs(" = ", fp); - while (space_ct-- > 0) fputc(' ', fp); - - /* - * IF the option is numeric only, - * THEN the char pointer is really the number - */ - if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NUMERIC) - fprintf(fp, "%d", (int)(intptr_t)l_arg); - - else { - for (;;) { - char const * eol = strchr(l_arg, NL); - - /* - * IF this is the last line - * THEN bail and print it - */ - if (eol == NULL) - break; - - /* - * Print the continuation and the text from the current line - */ - (void)fwrite(l_arg, (size_t)(eol - l_arg), (size_t)1, fp); - l_arg = eol+1; /* advance the Last Arg pointer */ - fputs("\\\n", fp); - } - - /* - * Terminate the entry - */ - fputs(l_arg, fp); - } - -end_entry: - fputc(NL, fp); -} - -/** - * print an option's value - * - * @param[in] fp the file pointer for the save file - * @param[in] od the option descriptor to print - */ -static void -prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp) -{ - while (--depth >= 0) - putc(' ', fp), putc(' ', fp); - - switch (ovp->valType) { - default: - case OPARG_TYPE_NONE: - fprintf(fp, NULL_ATR_FMT, ovp->pzName); - break; - - case OPARG_TYPE_STRING: - prt_string(fp, ovp->pzName, ovp->v.strVal); - break; - - case OPARG_TYPE_ENUMERATION: - case OPARG_TYPE_MEMBERSHIP: - if (od != NULL) { - uint32_t opt_state = od->fOptState; - uintptr_t val = od->optArg.argEnum; - char const * typ = (ovp->valType == OPARG_TYPE_ENUMERATION) - ? "keyword" : "set-membership"; - - fprintf(fp, TYPE_ATR_FMT, ovp->pzName, typ); - - /* - * This is a magic incantation that will convert the - * bit flag values back into a string suitable for printing. - */ - (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od ); - if (od->optArg.argString != NULL) { - fputs(od->optArg.argString, fp); - - if (ovp->valType != OPARG_TYPE_ENUMERATION) { - /* - * set membership strings get allocated - */ - AGFREE(od->optArg.argString); - } - } - - od->optArg.argEnum = val; - od->fOptState = opt_state; - fprintf(fp, END_XML_FMT, ovp->pzName); - break; - } - /* FALLTHROUGH */ - - case OPARG_TYPE_NUMERIC: - fprintf(fp, NUMB_ATR_FMT, ovp->pzName, ovp->v.longVal); - break; - - case OPARG_TYPE_BOOLEAN: - fprintf(fp, BOOL_ATR_FMT, ovp->pzName, - ovp->v.boolVal ? "true" : "false"); - break; - - case OPARG_TYPE_HIERARCHY: - prt_val_list(fp, ovp->pzName, ovp->v.nestVal); - break; - } -} - -/** - * Print a string value in XML format - * - * @param[in] fp the file pointer for the save file - */ -static void -prt_string(FILE * fp, char const * name, char const * pz) -{ - fprintf(fp, OPEN_XML_FMT, name); - for (;;) { - int ch = ((int)*(pz++)) & 0xFF; - - switch (ch) { - case NUL: goto string_done; - - case '&': - case '<': - case '>': -#if __GNUC__ >= 4 - case 1 ... (' ' - 1): - case ('~' + 1) ... 0xFF: -#endif - emit_special_char(fp, ch); - break; - - default: -#if __GNUC__ < 4 - if ( ((ch >= 1) && (ch <= (' ' - 1))) - || ((ch >= ('~' + 1)) && (ch <= 0xFF)) ) { - emit_special_char(fp, ch); - break; - } -#endif - putc(ch, fp); - } - } string_done:; - fprintf(fp, END_XML_FMT, name); -} - -/** - * Print an option that can have multiple values in XML format - * - * @param[in] fp file pointer - */ -static void -prt_val_list(FILE * fp, char const * name, tArgList * al) -{ - static int depth = 1; - - int sp_ct; - int opt_ct; - void ** opt_list; - - if (al == NULL) - return; - opt_ct = al->useCt; - opt_list = (void **)al->apzArgs; - - if (opt_ct <= 0) { - fprintf(fp, OPEN_CLOSE_FMT, name); - return; - } - - fprintf(fp, NESTED_OPT_FMT, name); - - depth++; - while (--opt_ct >= 0) { - tOptionValue const * ovp = *(opt_list++); - - prt_value(fp, depth, NULL, ovp); - } - depth--; - - for (sp_ct = depth; --sp_ct >= 0;) - putc(' ', fp), putc(' ', fp); - fprintf(fp, "\n", name); -} - -/** - * printed a nested/hierarchical value - * - * @param[in] fp file pointer - * @param[in] od option descriptor - * @param[in] save_fl include usage in comments - */ -static void -prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) -{ - int opt_ct; - tArgList * al = od->optCookie; - void ** opt_list; - - if (save_fl & SVFL_USAGE) - fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); - - /* - * Never show a default value if a hierarchical value is empty. - */ - if (UNUSED_OPT(od) || (al == NULL)) - return; - - opt_ct = al->useCt; - opt_list = (void **)al->apzArgs; - - if (opt_ct <= 0) - return; - - do { - tOptionValue const * base = *(opt_list++); - tOptionValue const * ovp = optionGetValue(base, NULL); - - if (ovp == NULL) - continue; - - fprintf(fp, NESTED_OPT_FMT, od->pz_Name); - - do { - prt_value(fp, 1, od, ovp); - - } while (ovp = optionNextValue(base, ovp), - ovp != NULL); - - fprintf(fp, "\n", od->pz_Name); - } while (--opt_ct > 0); -} - -/** - * remove the current program settings - * - * @param[in] opts the program options structure - * @param[in] fname the save file name - */ -static void -remove_settings(tOptions * opts, char const * fname) -{ - size_t const name_len = strlen(opts->pzProgName); - tmap_info_t map_info; - char * text = text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &map_info); - char * scan = text; - - for (;;) { - char * next = scan = strstr(scan, zCfgProg); - if (scan == NULL) - goto leave; - - scan = SPN_WHITESPACE_CHARS(scan + zCfgProg_LEN); - if ( (strneqvcmp(scan, opts->pzProgName, (int)name_len) == 0) - && (IS_END_XML_TOKEN_CHAR(scan[name_len])) ) { - - scan = next; - break; - } - } - - /* - * If not NULL, "scan" points to the "pzProgName, fname); - fprintf(stderr, zNoCreat, errno, strerror(errno), fname); - if (free_name) - AGFREE(fname); - return fp; - } - - if (free_name) - AGFREE(fname); - } - - do { - struct stat sbuf; - if (fstat(fileno(fp), &sbuf) < 0) - break; - - if (sbuf.st_size > zPresetFile_LEN) { - /* non-zero size implies save_fl is non-zero */ - fprintf(fp, zFmtProg, opts->pzProgName); - return fp; - } - } while (false); - - /* - * We have a new file. Insert a header - */ - fputs("# ", fp); - { - char const * e = strchr(opts->pzUsageTitle, NL); - if (e++ != NULL) - fwrite(opts->pzUsageTitle, 1, e - opts->pzUsageTitle, fp); - } - - { - time_t cur_time = time(NULL); - char * time_str = ctime(&cur_time); - - fprintf(fp, zPresetFile, time_str); -#ifdef HAVE_ALLOCATED_CTIME - /* - * The return values for ctime(), localtime(), and gmtime() - * normally point to static data that is overwritten by each call. - * The test to detect allocated ctime, so we leak the memory. - */ - AGFREE(time_str); -#endif - } - if (save_fl != 0) - fprintf(fp, zFmtProg, opts->pzProgName); - return fp; -} - -/** - * print option without an arg - * - * @param[in] fp file pointer - * @param[in] vod value option descriptor - * @param[in] pod primary option descriptor - * @param[in] save_fl include usage in comments - */ -static void -prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl) -{ - /* - * The aliased to argument indicates whether or not the option - * is "disabled". However, the original option has the name - * string, so we get that there, not with "vod". - */ - char const * pznm = - (DISABLED_OPT(vod)) ? pod->pz_DisableName : pod->pz_Name; - /* - * If the option was disabled and the disablement name is NULL, - * then the disablement was caused by aliasing. - * Use the name as the string to emit. - */ - if (pznm == NULL) - pznm = pod->pz_Name; - - if (save_fl & SVFL_USAGE) - fprintf(fp, ao_name_use_fmt, pod->pz_Name, pod->pzText); - if (UNUSED_OPT(pod) && (save_fl & SVFL_DEFAULT)) - fputs(ao_default_use, fp); - - fprintf(fp, "%s\n", pznm); -} - -/** - * print the string valued argument(s). - * - * @param[in] fp file pointer - * @param[in] od value option descriptor - * @param[in] save_fl include usage in comments - */ -static void -prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) -{ - if (UNUSED_OPT(od) || ((od->fOptState & OPTST_STACKED) == 0)) { - char const * arg = od->optArg.argString; - if (arg == NULL) - arg = "''"; - prt_entry(fp, od, arg, save_fl); - - } else { - tArgList * pAL = (tArgList *)od->optCookie; - int uct = pAL->useCt; - char const ** ppz = pAL->apzArgs; - - /* - * un-disable multiple copies of disabled options. - */ - if (uct > 1) - od->fOptState &= ~OPTST_DISABLED; - - while (uct-- > 0) { - prt_entry(fp, od, *(ppz++), save_fl); - save_fl &= ~SVFL_USAGE; - } - } -} - -/** - * print the string value of an enumeration. - * - * @param[in] fp the file pointer to write to - * @param[in] od the option descriptor with the enumerated value - * @param[in] save_fl include usage in comments - */ -static void -prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) -{ - uintptr_t val = od->optArg.argEnum; - - /* - * This is a magic incantation that will convert the - * bit flag values back into a string suitable for printing. - */ - (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); - prt_entry(fp, od, VOIDP(od->optArg.argString), save_fl); - - od->optArg.argEnum = val; -} - -/** - * Print the bits set in a bit mask option. - * - * We call the option handling function with a magic value for - * the options pointer and it allocates and fills in the string. - * We print that with a call to prt_entry(). - * - * @param[in] fp the file pointer to write to - * @param[in] od the option descriptor with a bit mask value type - * @param[in] save_fl include usage in comments - */ -static void -prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) -{ - char * list = optionMemberList(od); - size_t len = strlen(list); - char * buf = (char *)AGALOC(len + 3, "dir name"); - *buf= '='; - memcpy(buf+1, list, len + 1); - prt_entry(fp, od, buf, save_fl); - AGFREE(buf); - AGFREE(list); -} - -/** - * figure out what the option file name argument is. - * If one can be found, call prt_entry() to emit it. - * - * @param[in] fp the file pointer to write to. - * @param[in] od the option descriptor with a bit mask value type - * @param[in] opts the program options descriptor - * @param[in] save_fl include usage in comments - */ -static void -prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl) -{ - /* - * If the cookie is not NULL, then it has the file name, period. - * Otherwise, if we have a non-NULL string argument, then.... - */ - if (od->optCookie != NULL) - prt_entry(fp, od, od->optCookie, save_fl); - - else if (HAS_originalOptArgArray(opts)) { - char const * orig = - opts->originalOptArgArray[od->optIndex].argString; - - if (od->optArg.argString == orig) { - if (save_fl) - fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); - return; - } - - prt_entry(fp, od, od->optArg.argString, save_fl); - - } else if (save_fl) - fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); -} - -/*=export_func optionSaveFile - * - * what: saves the option state to a file - * - * arg: tOptions *, opts, program options descriptor - * - * doc: - * - * This routine will save the state of option processing to a file. The name - * of that file can be specified with the argument to the @code{--save-opts} - * option, or by appending the @code{rcfile} attribute to the last - * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it - * will default to @code{.@i{programname}rc}. If you wish to specify another - * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. - * - * The recommend usage is as follows: - * @example - * optionProcess(&progOptions, argc, argv); - * if (i_want_a_non_standard_place_for_this) - * SET_OPT_SAVE_OPTS("myfilename"); - * optionSaveFile(&progOptions); - * @end example - * - * err: - * - * If no @code{homerc} file was specified, this routine will silently return - * and do nothing. If the output file cannot be created or updated, a message - * will be printed to @code{stderr} and the routine will return. -=*/ -void -optionSaveFile(tOptions * opts) -{ - tOptDesc * od; - int ct; - FILE * fp; - save_flags_mask_t save_flags = SVFL_NONE; - - do { - char * temp_str; - char const * dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; - size_t flen; - - if (dir == NULL) - break; - temp_str = strchr(dir, '>'); - if (temp_str == NULL) - break; - if (temp_str[1] == '>') - save_flags = SVFL_UPDATE; - flen = (temp_str - dir); - if (flen == 0) - break; - temp_str = AGALOC(flen + 1, "flag search str"); - memcpy(temp_str, dir, flen); - temp_str[flen] = NUL; - save_flags |= save_flags_str2mask(temp_str, SVFL_NONE); - AGFREE(temp_str); - } while (false); - - fp = open_sv_file(opts, save_flags & SVFL_UPDATE); - if (fp == NULL) - return; - - /* - * FOR each of the defined options, ... - */ - ct = opts->presetOptCt; - od = opts->pOptDesc; - do { - tOptDesc * vod; - - /* - * Equivalenced options get picked up when the equivalenced-to - * option is processed. And do not save options with any state - * bits in the DO_NOT_SAVE collection - * - * ** option cannot be preset - * #define OPTST_NO_INIT 0x0000100U - * ** disable from cmd line - * #define OPTST_NO_COMMAND 0x2000000U - * ** alias for other option - * #define OPTST_ALIAS 0x8000000U - */ - if ((od->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0) - continue; - - if ( (od->optEquivIndex != NO_EQUIVALENT) - && (od->optEquivIndex != od->optIndex)) - continue; - - if (UNUSED_OPT(od) && ((save_flags & SVFL_USAGE_DEFAULT_MASK) == SVFL_NONE)) - continue; - - /* - * The option argument data are found at the equivalenced-to option, - * but the actual option argument type comes from the original - * option descriptor. Be careful! - */ - vod = ((od->fOptState & OPTST_EQUIVALENCE) != 0) - ? (opts->pOptDesc + od->optActualIndex) : od; - - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_NONE: - prt_no_arg_opt(fp, vod, od, save_flags); - break; - - case OPARG_TYPE_NUMERIC: - prt_entry(fp, vod, VOIDP(vod->optArg.argInt), save_flags); - break; - - case OPARG_TYPE_STRING: - prt_str_arg(fp, vod, save_flags); - break; - - case OPARG_TYPE_ENUMERATION: - prt_enum_arg(fp, vod, save_flags); - break; - - case OPARG_TYPE_MEMBERSHIP: - prt_set_arg(fp, vod, save_flags); - break; - - case OPARG_TYPE_BOOLEAN: - prt_entry(fp, vod, vod->optArg.argBool ? "true" : "false", save_flags); - break; - - case OPARG_TYPE_HIERARCHY: - prt_nested(fp, vod, save_flags); - break; - - case OPARG_TYPE_FILE: - prt_file_arg(fp, vod, opts, save_flags); - break; - - default: - break; /* cannot handle - skip it */ - } - } while (od++, (--ct > 0)); - - fclose(fp); -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/save.c */ diff --git a/src/libopts/sort.c b/src/libopts/sort.c deleted file mode 100644 index b4bd5cb..0000000 --- a/src/libopts/sort.c +++ /dev/null @@ -1,326 +0,0 @@ - -/* - * \file sort.c - * - * This module implements argument sorting. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/* - * "must_arg" and "maybe_arg" are really similar. The biggest - * difference is that "may" will consume the next argument only if it - * does not start with a hyphen and "must" will consume it, hyphen or not. - */ -static tSuccess -must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx) -{ - /* - * An option argument is required. Long options can either have - * a separate command line argument, or an argument attached by - * the '=' character. Figure out which. - */ - switch (pOS->optType) { - case TOPT_SHORT: - /* - * See if an arg string follows the flag character. If not, - * the next arg must be the option argument. - */ - if (*arg_txt != NUL) - return SUCCESS; - break; - - case TOPT_LONG: - /* - * See if an arg string has already been assigned (glued on - * with an `=' character). If not, the next is the opt arg. - */ - if (pOS->pzOptArg != NULL) - return SUCCESS; - break; - - default: - return FAILURE; - } - if (opts->curOptIdx >= opts->origArgCt) - return FAILURE; - - opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - return SUCCESS; -} - -static tSuccess -maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx) -{ - /* - * An option argument is optional. - */ - switch (pOS->optType) { - case TOPT_SHORT: - /* - * IF nothing is glued on after the current flag character, - * THEN see if there is another argument. If so and if it - * does *NOT* start with a hyphen, then it is the option arg. - */ - if (*arg_txt != NUL) - return SUCCESS; - break; - - case TOPT_LONG: - /* - * Look for an argument if we don't already have one (glued on - * with a `=' character) - */ - if (pOS->pzOptArg != NULL) - return SUCCESS; - break; - - default: - return FAILURE; - } - if (opts->curOptIdx >= opts->origArgCt) - return PROBLEM; - - arg_txt = opts->origArgVect[ opts->curOptIdx ]; - if (*arg_txt != '-') - opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - return SUCCESS; -} - -/* - * Process a string of short options glued together. If the last one - * does or may take an argument, the do the argument processing and leave. - */ -static tSuccess -short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, - char ** opt_txt, uint32_t * opt_idx) -{ - while (*arg_txt != NUL) { - if (FAILED(opt_find_short(opts, (uint8_t)*arg_txt, pOS))) - return FAILURE; - - /* - * See if we can have an arg. - */ - if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { - arg_txt++; - - } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { - /* - * Take an argument if it is not attached and it does not - * start with a hyphen. - */ - if (arg_txt[1] != NUL) - return SUCCESS; - - arg_txt = opts->origArgVect[ opts->curOptIdx ]; - if (*arg_txt != '-') - opt_txt[ (*opt_idx)++ ] = - opts->origArgVect[ (opts->curOptIdx)++ ]; - return SUCCESS; - - } else { - /* - * IF we need another argument, be sure it is there and - * take it. - */ - if (arg_txt[1] == NUL) { - if (opts->curOptIdx >= opts->origArgCt) - return FAILURE; - opt_txt[ (*opt_idx)++ ] = - opts->origArgVect[ (opts->curOptIdx)++ ]; - } - return SUCCESS; - } - } - return SUCCESS; -} - -/* - * If the program wants sorted options (separated operands and options), - * then this routine will to the trick. - */ -static void -optionSort(tOptions * opts) -{ - char ** opt_txt; - char ** ppzOpds; - uint32_t optsIdx = 0; - uint32_t opdsIdx = 0; - - tOptState os = OPTSTATE_INITIALIZER(DEFINED); - - /* - * Disable for POSIX conformance, or if there are no operands. - */ - if ( (getenv("POSIXLY_CORRECT") != NULL) - || NAMED_OPTS(opts)) - return; - - /* - * Make sure we can allocate two full-sized arg vectors. - */ - opt_txt = malloc(opts->origArgCt * sizeof(char *)); - if (opt_txt == NULL) - goto exit_no_mem; - - ppzOpds = malloc(opts->origArgCt * sizeof(char *)); - if (ppzOpds == NULL) { - free(opt_txt); - goto exit_no_mem; - } - - opts->curOptIdx = 1; - opts->pzCurOpt = NULL; - - /* - * Now, process all the options from our current position onward. - * (This allows interspersed options and arguments for the few - * non-standard programs that require it.) - */ - for (;;) { - char * arg_txt; - tSuccess res; - - /* - * If we're out of arguments, we're done. Join the option and - * operand lists into the original argument vector. - */ - if (opts->curOptIdx >= opts->origArgCt) { - errno = 0; - goto joinLists; - } - - arg_txt = opts->origArgVect[ opts->curOptIdx ]; - if (*arg_txt != '-') { - ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - continue; - } - - switch (arg_txt[1]) { - case NUL: - /* - * A single hyphen is an operand. - */ - ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - continue; - - case '-': - /* - * Two consecutive hypens. Put them on the options list and then - * _always_ force the remainder of the arguments to be operands. - */ - if (arg_txt[2] == NUL) { - opt_txt[ optsIdx++ ] = - opts->origArgVect[ (opts->curOptIdx)++ ]; - goto restOperands; - } - res = opt_find_long(opts, arg_txt+2, &os); - break; - - default: - /* - * If short options are not allowed, then do long - * option processing. Otherwise the character must be a - * short (i.e. single character) option. - */ - if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) { - res = opt_find_long(opts, arg_txt+1, &os); - } else { - res = opt_find_short(opts, (uint8_t)arg_txt[1], &os); - } - break; - } - if (FAILED(res)) { - errno = EINVAL; - goto freeTemps; - } - - /* - * We've found an option. Add the argument to the option list. - * Next, we have to see if we need to pull another argument to be - * used as the option argument. - */ - opt_txt[ optsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - - if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) { - /* - * No option argument. If we have a short option here, - * then scan for short options until we get to the end - * of the argument string. - */ - if ( (os.optType == TOPT_SHORT) - && FAILED(short_opt_ck(opts, arg_txt+2, &os, opt_txt, - &optsIdx)) ) { - errno = EINVAL; - goto freeTemps; - } - - } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) { - switch (maybe_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { - case FAILURE: errno = EIO; goto freeTemps; - case PROBLEM: errno = 0; goto joinLists; - } - - } else { - switch (must_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { - case PROBLEM: - case FAILURE: errno = EIO; goto freeTemps; - } - } - } /* for (;;) */ - - restOperands: - while (opts->curOptIdx < opts->origArgCt) - ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; - - joinLists: - if (optsIdx > 0) - memcpy(opts->origArgVect + 1, opt_txt, - (size_t)optsIdx * sizeof(char *)); - if (opdsIdx > 0) - memcpy(opts->origArgVect + 1 + optsIdx, ppzOpds, - (size_t)opdsIdx * sizeof(char *)); - - freeTemps: - free(opt_txt); - free(ppzOpds); - return; - - exit_no_mem: - errno = ENOMEM; - return; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/sort.c */ diff --git a/src/libopts/stack.c b/src/libopts/stack.c deleted file mode 100644 index 39a328a..0000000 --- a/src/libopts/stack.c +++ /dev/null @@ -1,267 +0,0 @@ - -/** - * \file stack.c - * - * This is a special option processing routine that will save the - * argument to an option in a FIFO queue. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -#ifdef WITH_LIBREGEX -# include REGEX_HEADER -#endif - -/*=export_func optionUnstackArg - * private: - * - * what: Remove option args from a stack - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Invoked for options that are equivalenced to stacked options. -=*/ -void -optionUnstackArg(tOptions * opts, tOptDesc * od) -{ - tArgList * arg_list; - - if (INQUERY_CALL(opts, od)) - return; - - arg_list = (tArgList *)od->optCookie; - - /* - * IF we don't have any stacked options, - * THEN indicate that we don't have any of these options - */ - if (arg_list == NULL) { - od->fOptState &= OPTST_PERSISTENT_MASK; - if ((od->fOptState & OPTST_INITENABLED) == 0) - od->fOptState |= OPTST_DISABLED; - return; - } - -#ifdef WITH_LIBREGEX - { - regex_t re; - int i, ct, dIdx; - - if (regcomp(&re, od->optArg.argString, REG_NOSUB) != 0) - return; - - /* - * search the list for the entry(s) to remove. Entries that - * are removed are *not* copied into the result. The source - * index is incremented every time. The destination only when - * we are keeping a define. - */ - for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { - char const * pzSrc = arg_list->apzArgs[ i ]; - char * pzEq = strchr(pzSrc, '='); - int res; - - - if (pzEq != NULL) - *pzEq = NUL; - - res = regexec(&re, pzSrc, (size_t)0, NULL, 0); - switch (res) { - case 0: - /* - * Remove this entry by reducing the in-use count - * and *not* putting the string pointer back into - * the list. - */ - AGFREE(pzSrc); - arg_list->useCt--; - break; - - default: - case REG_NOMATCH: - if (pzEq != NULL) - *pzEq = '='; - - /* - * IF we have dropped an entry - * THEN we have to move the current one. - */ - if (dIdx != i) - arg_list->apzArgs[ dIdx ] = pzSrc; - dIdx++; - } - } - - regfree(&re); - } -#else /* not WITH_LIBREGEX */ - { - int i, ct, dIdx; - - /* - * search the list for the entry(s) to remove. Entries that - * are removed are *not* copied into the result. The source - * index is incremented every time. The destination only when - * we are keeping a define. - */ - for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { - const char * pzSrc = arg_list->apzArgs[ i ]; - char * pzEq = strchr(pzSrc, '='); - - if (pzEq != NULL) - *pzEq = NUL; - - if (strcmp(pzSrc, od->optArg.argString) == 0) { - /* - * Remove this entry by reducing the in-use count - * and *not* putting the string pointer back into - * the list. - */ - AGFREE(pzSrc); - arg_list->useCt--; - } else { - if (pzEq != NULL) - *pzEq = '='; - - /* - * IF we have dropped an entry - * THEN we have to move the current one. - */ - if (dIdx != i) - arg_list->apzArgs[ dIdx ] = pzSrc; - dIdx++; - } - } - } -#endif /* WITH_LIBREGEX */ - /* - * IF we have unstacked everything, - * THEN indicate that we don't have any of these options - */ - if (arg_list->useCt == 0) { - od->fOptState &= OPTST_PERSISTENT_MASK; - if ((od->fOptState & OPTST_INITENABLED) == 0) - od->fOptState |= OPTST_DISABLED; - AGFREE(arg_list); - od->optCookie = NULL; - } -} - - -/* - * Put an entry into an argument list. The first argument points to - * a pointer to the argument list structure. It gets passed around - * as an opaque address. - */ -static void -addArgListEntry(void ** ppAL, void * entry) -{ - tArgList * pAL = *(void **)ppAL; - - /* - * IF we have never allocated one of these, - * THEN allocate one now - */ - if (pAL == NULL) { - pAL = (tArgList *)AGALOC(sizeof(*pAL), "new option arg stack"); - if (pAL == NULL) - return; - pAL->useCt = 0; - pAL->allocCt = MIN_ARG_ALLOC_CT; - *ppAL = VOIDP(pAL); - } - - /* - * ELSE if we are out of room - * THEN make it bigger - */ - else if (pAL->useCt >= pAL->allocCt) { - size_t sz = sizeof(*pAL); - pAL->allocCt += INCR_ARG_ALLOC_CT; - - /* - * The base structure contains space for MIN_ARG_ALLOC_CT - * pointers. We subtract it off to find our augment size. - */ - sz += sizeof(char *) * ((size_t)pAL->allocCt - MIN_ARG_ALLOC_CT); - pAL = (tArgList *)AGREALOC(VOIDP(pAL), sz, "expanded opt arg stack"); - if (pAL == NULL) - return; - *ppAL = VOIDP(pAL); - } - - /* - * Insert the new argument into the list - */ - pAL->apzArgs[ (pAL->useCt)++ ] = entry; -} - - -/*=export_func optionStackArg - * private: - * - * what: put option args on a stack - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Keep an entry-ordered list of option arguments. -=*/ -void -optionStackArg(tOptions * opts, tOptDesc * od) -{ - char * pz; - - if (INQUERY_CALL(opts, od)) - return; - - if ((od->fOptState & OPTST_RESET) != 0) { - tArgList * arg_list = od->optCookie; - int ix; - if (arg_list == NULL) - return; - - ix = arg_list->useCt; - while (--ix >= 0) - AGFREE(arg_list->apzArgs[ix]); - AGFREE(arg_list); - - } else { - if (od->optArg.argString == NULL) - return; - - AGDUPSTR(pz, od->optArg.argString, "stack arg"); - addArgListEntry(&(od->optCookie), VOIDP(pz)); - } -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/stack.c */ diff --git a/src/libopts/stdnoreturn.in.h b/src/libopts/stdnoreturn.in.h deleted file mode 100644 index bf46c08..0000000 --- a/src/libopts/stdnoreturn.in.h +++ /dev/null @@ -1,60 +0,0 @@ -/* A substitute for ISO C11 . - - Copyright 2012-2018 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, see . */ - -/* Written by Paul Eggert. */ - -#ifndef noreturn - -/* ISO C11 for platforms that lack it. - - References: - ISO C11 (latest free draft - ) - section 7.23 */ - -/* The definition of _Noreturn is copied here. */ - -#if 1200 <= _MSC_VER || defined __CYGWIN__ -/* On MSVC, standard include files contain declarations like - __declspec (noreturn) void abort (void); - "#define noreturn _Noreturn" would cause this declaration to be rewritten - to the invalid - __declspec (__declspec (noreturn)) void abort (void); - - Similarly, on Cygwin, standard include files contain declarations like - void __cdecl abort (void) __attribute__ ((noreturn)); - "#define noreturn _Noreturn" would cause this declaration to be rewritten - to the invalid - void __cdecl abort (void) __attribute__ ((__attribute__ ((__noreturn__)))); - - Instead, define noreturn to empty, so that such declarations are rewritten to - __declspec () void abort (void); - or - void __cdecl abort (void) __attribute__ (()); - respectively. This gives up on noreturn's advice to the compiler but at - least it is valid code. */ -# define noreturn /*empty*/ -#else -# define noreturn _Noreturn -#endif - -/* Did he ever return? - No he never returned - And his fate is still unlearn'd ... - -- Steiner J, Hawes BL. M.T.A. (1949) */ - -#endif /* noreturn */ diff --git a/src/libopts/streqvcmp.c b/src/libopts/streqvcmp.c deleted file mode 100644 index 53477d6..0000000 --- a/src/libopts/streqvcmp.c +++ /dev/null @@ -1,284 +0,0 @@ - -/** - * \file streqvcmp.c - * - * String Equivalence Comparison - * - * These routines allow any character to be mapped to any other - * character before comparison. In processing long option names, - * the characters "-", "_" and "^" all need to be equivalent - * (because they are treated so by different development environments). - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - * - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ - static unsigned char charmap[] = { - NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a', - '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - - ' ', '!', '"', '#', '$', '%', '&', '\'', - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - - '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - 'x', 'y', 'z', '[', '\\', ']', '^', '_', - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, - - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, - 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, - 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, - 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, - - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, - 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, - 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, - 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, -}; - - -/*=export_func strneqvcmp - * - * what: compare two strings with an equivalence mapping - * - * arg: + char const * + str1 + first string + - * arg: + char const * + str2 + second string + - * arg: + int + ct + compare length + - * - * ret_type: int - * ret_desc: the difference between two differing characters - * - * doc: - * - * Using a character mapping, two strings are compared for "equivalence". - * Each input character is mapped to a comparison character and the - * mapped-to characters are compared for the two NUL terminated input strings. - * The comparison is limited to @code{ct} bytes. - * This function name is mapped to option_strneqvcmp so as to not conflict - * with the POSIX name space. - * - * err: none checked. Caller responsible for seg faults. -=*/ -int -strneqvcmp(char const * s1, char const * s2, int ct) -{ - for (; ct > 0; --ct) { - unsigned char u1 = (unsigned char) *s1++; - unsigned char u2 = (unsigned char) *s2++; - int dif; - if (u1 == u2) { - if (u1 == NUL) - return 0; - continue; - } - - dif = charmap[ u1 ] - charmap[ u2 ]; - - if (dif != 0) - return dif; - - if (u1 == NUL) - return 0; - } - - return 0; -} - - -/*=export_func streqvcmp - * - * what: compare two strings with an equivalence mapping - * - * arg: + char const * + str1 + first string + - * arg: + char const * + str2 + second string + - * - * ret_type: int - * ret_desc: the difference between two differing characters - * - * doc: - * - * Using a character mapping, two strings are compared for "equivalence". - * Each input character is mapped to a comparison character and the - * mapped-to characters are compared for the two NUL terminated input strings. - * This function name is mapped to option_streqvcmp so as to not conflict - * with the POSIX name space. - * - * err: none checked. Caller responsible for seg faults. -=*/ -int -streqvcmp(char const * s1, char const * s2) -{ - for (;;) { - unsigned char u1 = (unsigned char) *s1++; - unsigned char u2 = (unsigned char) *s2++; - int dif; - if (u1 == u2) { - if (u1 == NUL) - return 0; - continue; - } - - dif = charmap[ u1 ] - charmap[ u2 ]; - - if (dif != 0) - return dif; - - if (u1 == NUL) - return 0; - } -} - - -/*=export_func streqvmap - * - * what: Set the character mappings for the streqv functions - * - * arg: + char + from + Input character + - * arg: + char + to + Mapped-to character + - * arg: + int + ct + compare length + - * - * doc: - * - * Set the character mapping. If the count (@code{ct}) is set to zero, then - * the map is cleared by setting all entries in the map to their index - * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" - * character. If @code{ct} is greater than 1, then @code{From} and @code{To} - * are incremented and the process repeated until @code{ct} entries have been - * set. For example, - * @example - * streqvmap('a', 'A', 26); - * @end example - * @noindent - * will alter the mapping so that all English lower case letters - * will map to upper case. - * - * This function name is mapped to option_streqvmap so as to not conflict - * with the POSIX name space. - * - * err: none. -=*/ -void -streqvmap(char from, char to, int ct) -{ - if (ct == 0) { - ct = sizeof(charmap) - 1; - do { - charmap[ct] = (unsigned char)ct; - } while (--ct >= 0); - } - - else { - unsigned int i_to = (int)to & 0xFF; - unsigned int i_from = (int)from & 0xFF; - - do { - charmap[i_from] = (unsigned char)i_to; - i_from++; - i_to++; - if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap))) - break; - } while (--ct > 0); - } -} - - -/*=export_func strequate - * - * what: map a list of characters to the same value - * - * arg: + char const * + ch_list + characters to equivalence + - * - * doc: - * - * Each character in the input string get mapped to the first character - * in the string. - * This function name is mapped to option_strequate so as to not conflict - * with the POSIX name space. - * - * err: none. -=*/ -void -strequate(char const * s) -{ - if ((s != NULL) && (*s != NUL)) { - unsigned char equiv = (unsigned char)*s; - while (*s != NUL) - charmap[(unsigned char)*(s++)] = equiv; - } -} - - -/*=export_func strtransform - * - * what: convert a string into its mapped-to value - * - * arg: + char * + dest + output string + - * arg: + char const * + src + input string + - * - * doc: - * - * Each character in the input string is mapped and the mapped-to - * character is put into the output. - * This function name is mapped to option_strtransform so as to not conflict - * with the POSIX name space. - * - * The source and destination may be the same. - * - * err: none. -=*/ -void -strtransform(char * d, char const * s) -{ - do { - *(d++) = (char)charmap[(unsigned char)*s]; - } while (*(s++) != NUL); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/streqvcmp.c */ diff --git a/src/libopts/text_mmap.c b/src/libopts/text_mmap.c deleted file mode 100644 index 1109308..0000000 --- a/src/libopts/text_mmap.c +++ /dev/null @@ -1,382 +0,0 @@ -/** - * @file text_mmap.c - * - * Map a text file, ensuring the text always has an ending NUL byte. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ -#if defined(HAVE_MMAP) -# ifndef MAP_ANONYMOUS -# ifdef MAP_ANON -# define MAP_ANONYMOUS MAP_ANON -# endif -# endif - -# if ! defined(MAP_ANONYMOUS) && ! defined(HAVE_DEV_ZERO) - /* - * We must have either /dev/zero or anonymous mapping for - * this to work. - */ -# undef HAVE_MMAP - -# else -# ifdef _SC_PAGESIZE -# define GETPAGESIZE() sysconf(_SC_PAGESIZE) -# else -# define GETPAGESIZE() getpagesize() -# endif -# endif -#endif - -/* - * Some weird systems require that a specifically invalid FD number - * get passed in as an argument value. Which value is that? Well, - * as everybody knows, if open(2) fails, it returns -1, so that must - * be the value. :) - */ -#define AO_INVALID_FD -1 - -#define FILE_WRITABLE(_prt,_flg) \ - ( (_prt & PROT_WRITE) \ - && ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED)) -#define MAP_FAILED_PTR (VOIDP(MAP_FAILED)) - -/** - * Load the contents of a text file. There are two separate implementations, - * depending up on whether mmap(3) is available. - * - * If not available, malloc the file length plus one byte. Read it in - * and NUL terminate. - * - * If available, first check to see if the text file size is a multiple of a - * page size. If it is, map the file size plus an extra page from either - * anonymous memory or from /dev/zero. Then map the file text on top of the - * first pages of the anonymous/zero pages. Otherwise, just map the file - * because there will be NUL bytes provided at the end. - * - * @param mapinfo a structure holding everything we need to know - * about the mapping. - * - * @param pzFile name of the file, for error reporting. - */ -static void -load_text_file(tmap_info_t * mapinfo, char const * pzFile) -{ -#if ! defined(HAVE_MMAP) - mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text"); - if (mapinfo->txt_data == NULL) { - mapinfo->txt_errno = ENOMEM; - return; - } - - { - size_t sz = mapinfo->txt_size; - char * pz = mapinfo->txt_data; - - while (sz > 0) { - ssize_t rdct = read(mapinfo->txt_fd, pz, sz); - if (rdct <= 0) { - mapinfo->txt_errno = errno; - fserr_warn("libopts", "read", pzFile); - free(mapinfo->txt_data); - return; - } - - pz += rdct; - sz -= rdct; - } - - *pz = NUL; - } - - mapinfo->txt_errno = 0; - -#else /* HAVE mmap */ - size_t const pgsz = (size_t)GETPAGESIZE(); - void * map_addr = NULL; - - (void)pzFile; - - mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1); - if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) { - /* - * The text is a multiple of a page boundary. We must map an - * extra page so the text ends with a NUL. - */ -#if defined(MAP_ANONYMOUS) - map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, - MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0); -#else - mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY); - - if (mapinfo->txt_zero_fd == AO_INVALID_FD) { - mapinfo->txt_errno = errno; - return; - } - map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, - MAP_PRIVATE, mapinfo->txt_zero_fd, 0); -#endif - if (map_addr == MAP_FAILED_PTR) { - mapinfo->txt_errno = errno; - return; - } - mapinfo->txt_flags |= MAP_FIXED; - } - - mapinfo->txt_data = - mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot, - mapinfo->txt_flags, mapinfo->txt_fd, 0); - - if (mapinfo->txt_data == MAP_FAILED_PTR) - mapinfo->txt_errno = errno; -#endif /* HAVE_MMAP */ -} - -/** - * Make sure all the parameters are correct: we have a file name that - * is a text file that we can read. - * - * @param fname the text file to map - * @param prot the memory protections requested (read/write/etc.) - * @param flags mmap flags - * @param mapinfo a structure holding everything we need to know - * about the mapping. - */ -static void -validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo) -{ - memset(mapinfo, 0, sizeof(*mapinfo)); -#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) - mapinfo->txt_zero_fd = AO_INVALID_FD; -#endif - mapinfo->txt_fd = AO_INVALID_FD; - mapinfo->txt_prot = prot; - mapinfo->txt_flags = flags; - - /* - * Map mmap flags and protections into open flags and do the open. - */ - { - /* - * See if we will be updating the file. If we can alter the memory - * and if we share the data and we are *not* copy-on-writing the data, - * then our updates will show in the file, so we must open with - * write access. - */ - int o_flag = -#ifdef _WIN32 - O_BINARY | -#endif - FILE_WRITABLE(prot, flags) ? O_RDWR : O_RDONLY; - - /* - * If you're not sharing the file and you are writing to it, - * then don't let anyone else have access to the file. - */ - if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE)) - o_flag |= O_EXCL; - - mapinfo->txt_fd = open(fname, o_flag); - if (mapinfo->txt_fd < 0) { - mapinfo->txt_errno = errno; - mapinfo->txt_fd = AO_INVALID_FD; - return; - } - } - - /* - * Make sure we can stat the regular file. Save the file size. - */ - { - struct stat sb; - if (fstat(mapinfo->txt_fd, &sb) != 0) { - mapinfo->txt_errno = errno; - close(mapinfo->txt_fd); - return; - } - - if (! S_ISREG(sb.st_mode)) { - mapinfo->txt_errno = errno = EINVAL; - close(mapinfo->txt_fd); - return; - } - - mapinfo->txt_size = (size_t)sb.st_size; - } - - if (mapinfo->txt_fd == AO_INVALID_FD) - mapinfo->txt_errno = errno; -} - -/** - * Close any files opened by the mapping. - * - * @param mi a structure holding everything we need to know about the map. - */ -static void -close_mmap_files(tmap_info_t * mi) -{ - if (mi->txt_fd == AO_INVALID_FD) - return; - - close(mi->txt_fd); - mi->txt_fd = AO_INVALID_FD; - -#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) - if (mi->txt_zero_fd == AO_INVALID_FD) - return; - - close(mi->txt_zero_fd); - mi->txt_zero_fd = AO_INVALID_FD; -#endif -} - -/*=export_func text_mmap - * private: - * - * what: map a text file with terminating NUL - * - * arg: char const *, pzFile, name of the file to map - * arg: int, prot, mmap protections (see mmap(2)) - * arg: int, flags, mmap flags (see mmap(2)) - * arg: tmap_info_t *, mapinfo, returned info about the mapping - * - * ret-type: void * - * ret-desc: The mmaped data address - * - * doc: - * - * This routine will mmap a file into memory ensuring that there is at least - * one @file{NUL} character following the file data. It will return the - * address where the file contents have been mapped into memory. If there is a - * problem, then it will return @code{MAP_FAILED} and set @code{errno} - * appropriately. - * - * The named file does not exist, @code{stat(2)} will set @code{errno} as it - * will. If the file is not a regular file, @code{errno} will be - * @code{EINVAL}. At that point, @code{open(2)} is attempted with the access - * bits set appropriately for the requested @code{mmap(2)} protections and flag - * bits. On failure, @code{errno} will be set according to the documentation - * for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as - * that routine sets it. If @code{text_mmap} works to this point, a valid - * address will be returned, but there may still be ``issues''. - * - * If the file size is not an even multiple of the system page size, then - * @code{text_map} will return at this point and @code{errno} will be zero. - * Otherwise, an anonymous map is attempted. If not available, then an attempt - * is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the - * address of the file's data is returned, bug @code{no} @file{NUL} characters - * are mapped after the end of the data. - * - * see: mmap(2), open(2), stat(2) - * - * err: Any error code issued by mmap(2), open(2), stat(2) is possible. - * Additionally, if the specified file is not a regular file, then - * errno will be set to @code{EINVAL}. - * - * example: - * #include - * tmap_info_t mi; - * int no_nul; - * void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi); - * if (data == MAP_FAILED) return; - * no_nul = (mi.txt_size == mi.txt_full_size); - * << use the data >> - * text_munmap(&mi); -=*/ -void * -text_mmap(char const * pzFile, int prot, int flags, tmap_info_t * mi) -{ - validate_mmap(pzFile, prot, flags, mi); - if (mi->txt_errno != 0) - return MAP_FAILED_PTR; - - load_text_file(mi, pzFile); - - if (mi->txt_errno == 0) - return mi->txt_data; - - close_mmap_files(mi); - - errno = mi->txt_errno; - mi->txt_data = MAP_FAILED_PTR; - return mi->txt_data; -} - - -/*=export_func text_munmap - * private: - * - * what: unmap the data mapped in by text_mmap - * - * arg: tmap_info_t *, mapinfo, info about the mapping - * - * ret-type: int - * ret-desc: -1 or 0. @code{errno} will have the error code. - * - * doc: - * - * This routine will unmap the data mapped in with @code{text_mmap} and close - * the associated file descriptors opened by that function. - * - * see: munmap(2), close(2) - * - * err: Any error code issued by munmap(2) or close(2) is possible. -=*/ -int -text_munmap(tmap_info_t * mi) -{ - errno = 0; - -#ifdef HAVE_MMAP - (void)munmap(mi->txt_data, mi->txt_full_size); - -#else // don't HAVE_MMAP - /* - * IF the memory is writable *AND* it is not private (copy-on-write) - * *AND* the memory is "sharable" (seen by other processes) - * THEN rewrite the data. Emulate mmap visibility. - */ - if ( FILE_WRITABLE(mi->txt_prot, mi->txt_flags) - && (lseek(mi->txt_fd, 0, SEEK_SET) >= 0) ) - write(mi->txt_fd, mi->txt_data, mi->txt_size); - - free(mi->txt_data); -#endif /* HAVE_MMAP */ - - mi->txt_errno = errno; - close_mmap_files(mi); - - return mi->txt_errno; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/text_mmap.c */ diff --git a/src/libopts/time.c b/src/libopts/time.c deleted file mode 100644 index debaa7a..0000000 --- a/src/libopts/time.c +++ /dev/null @@ -1,145 +0,0 @@ - -/** - * \file time.c - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/*=export_func optionTimeVal - * private: - * - * what: process an option with a time duration. - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Decipher a time duration value. -=*/ -void -optionTimeVal(tOptions * opts, tOptDesc * od) -{ - time_t val; - - if (INQUERY_CALL(opts, od)) - return; - - val = parse_duration(od->optArg.argString); - if (val == BAD_TIME) { - fprintf(stderr, zNotDuration, opts->pzProgName, od->optArg.argString); - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - (*(opts->pUsageProc))(opts, EXIT_FAILURE); - } - - if (od->fOptState & OPTST_ALLOC_ARG) { - AGFREE(od->optArg.argString); - od->fOptState &= ~OPTST_ALLOC_ARG; - } - - od->optArg.argInt = (long)val; -} - -/*=export_func optionTimeDate - * private: - * - * what: process an option with a time and date. - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * Decipher a time and date value. -=*/ -void -optionTimeDate(tOptions * opts, tOptDesc * od) -{ -#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV) - if (INQUERY_CALL(opts, od)) - return; - - if ((! HAS_pzPkgDataDir(opts)) || (opts->pzPkgDataDir == NULL)) - goto default_action; - - /* - * Export the DATEMSK environment variable. getdate_r() uses it to - * find the file with the strptime formats. If we cannot find the file - * we need ($PKGDATADIR/datemsk), then fall back to just a time duration. - */ - { - static char * envptr = NULL; - - if (envptr == NULL) { - static char const fmt[] = "DATEMSK=%s/datemsk"; - size_t sz = sizeof(fmt) + strlen(opts->pzPkgDataDir); - envptr = AGALOC(sz, fmt); - if (snprintf(envptr, sz, fmt, opts->pzPkgDataDir) >= (int)sz) - option_exits(EXIT_FAILURE); - - putenv(envptr); - } - - if (access(envptr+8, R_OK) != 0) - goto default_action; - } - - /* - * Convert the date to a time since the epoch and stash it in a long int. - */ - { - struct tm stm; - time_t tm; - - if (getdate_r(od->optArg.argString, &stm) != 0) { - fprintf(stderr, zNotDate, opts->pzProgName, - od->optArg.argString); - if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) - (*(opts->pUsageProc))(opts, EXIT_FAILURE); - return; - } - - tm = mktime(&stm); - - if (od->fOptState & OPTST_ALLOC_ARG) { - AGFREE(od->optArg.argString); - od->fOptState &= ~OPTST_ALLOC_ARG; - } - - od->optArg.argInt = tm; - } - return; - - default_action: - -#endif - optionTimeVal(opts, od); - if (od->optArg.argInt != BAD_TIME) - od->optArg.argInt += (long)time(NULL); -} -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/time.c */ diff --git a/src/libopts/tokenize.c b/src/libopts/tokenize.c deleted file mode 100644 index 7489e3d..0000000 --- a/src/libopts/tokenize.c +++ /dev/null @@ -1,322 +0,0 @@ -/** \file tokenize.c - * - * Tokenize a string, accommodating quoted strings. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file defines the string_tokenize interface - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -static void -copy_cooked(ch_t ** ppDest, char const ** ppSrc) -{ - ch_t * pDest = (ch_t *)*ppDest; - const ch_t * pSrc = (const ch_t *)(*ppSrc + 1); - - for (;;) { - ch_t ch = *(pSrc++); - switch (ch) { - case NUL: *ppSrc = NULL; return; - case '"': goto done; - case '\\': - pSrc += ao_string_cook_escape_char((char *)pSrc, (char *)&ch, 0x7F); - if (ch == 0x7F) - break; - /* FALLTHROUGH */ - - default: - *(pDest++) = ch; - } - } - - done: - *ppDest = (ch_t *)pDest; /* next spot for storing character */ - *ppSrc = (char const *)pSrc; /* char following closing quote */ -} - - -static void -copy_raw(ch_t ** ppDest, char const ** ppSrc) -{ - ch_t * pDest = *ppDest; - cc_t * pSrc = (cc_t *) (*ppSrc + 1); - - for (;;) { - ch_t ch = *(pSrc++); - switch (ch) { - case NUL: *ppSrc = NULL; return; - case '\'': goto done; - case '\\': - /* - * *Four* escapes are handled: newline removal, escape char - * quoting and apostrophe quoting - */ - switch (*pSrc) { - case NUL: *ppSrc = NULL; return; - case '\r': - if (*(++pSrc) == NL) - ++pSrc; - continue; - - case NL: - ++pSrc; - continue; - - case '\'': - ch = '\''; - /* FALLTHROUGH */ - - case '\\': - ++pSrc; - break; - } - /* FALLTHROUGH */ - - default: - *(pDest++) = ch; - } - } - - done: - *ppDest = pDest; /* next spot for storing character */ - *ppSrc = (char const *) pSrc; /* char following closing quote */ -} - -static token_list_t * -alloc_token_list(char const * str) -{ - token_list_t * res; - - int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */ - - if (str == NULL) goto enoent_res; - - /* - * Trim leading white space. Use "ENOENT" and a NULL return to indicate - * an empty string was passed. - */ - str = SPN_WHITESPACE_CHARS(str); - if (*str == NUL) goto enoent_res; - - /* - * Take an approximate count of tokens. If no quoted strings are used, - * it will be accurate. If quoted strings are used, it will be a little - * high and we'll squander the space for a few extra pointers. - */ - { - char const * pz = str; - - do { - max_token_ct++; - pz = BRK_WHITESPACE_CHARS(pz+1); - pz = SPN_WHITESPACE_CHARS(pz); - } while (*pz != NUL); - - res = malloc(sizeof(*res) + (size_t)(pz - str) - + ((size_t)max_token_ct * sizeof(ch_t *))); - } - - if (res == NULL) - errno = ENOMEM; - else res->tkn_list[0] = (ch_t *)(res->tkn_list + (max_token_ct - 1)); - - return res; - - enoent_res: - - errno = ENOENT; - return NULL; -} - -/*=export_func ao_string_tokenize - * - * what: tokenize an input string - * - * arg: + char const * + string + string to be tokenized + - * - * ret_type: token_list_t * - * ret_desc: pointer to a structure that lists each token - * - * doc: - * - * This function will convert one input string into a list of strings. - * The list of strings is derived by separating the input based on - * white space separation. However, if the input contains either single - * or double quote characters, then the text after that character up to - * a matching quote will become the string in the list. - * - * The returned pointer should be deallocated with @code{free(3C)} when - * are done using the data. The data are placed in a single block of - * allocated memory. Do not deallocate individual token/strings. - * - * The structure pointed to will contain at least these two fields: - * @table @samp - * @item tkn_ct - * The number of tokens found in the input string. - * @item tok_list - * An array of @code{tkn_ct + 1} pointers to substring tokens, with - * the last pointer set to NULL. - * @end table - * - * There are two types of quoted strings: single quoted (@code{'}) and - * double quoted (@code{"}). Singly quoted strings are fairly raw in that - * escape characters (@code{\\}) are simply another character, except when - * preceding the following characters: - * @example - * @code{\\} double backslashes reduce to one - * @code{'} incorporates the single quote into the string - * @code{\n} suppresses both the backslash and newline character - * @end example - * - * Double quote strings are formed according to the rules of string - * constants in ANSI-C programs. - * - * example: - * @example - * #include - * int ix; - * token_list_t * ptl = ao_string_tokenize(some_string) - * for (ix = 0; ix < ptl->tkn_ct; ix++) - * do_something_with_tkn(ptl->tkn_list[ix]); - * free(ptl); - * @end example - * Note that everything is freed with the one call to @code{free(3C)}. - * - * err: - * NULL is returned and @code{errno} will be set to indicate the problem: - * @itemize @bullet - * @item - * @code{EINVAL} - There was an unterminated quoted string. - * @item - * @code{ENOENT} - The input string was empty. - * @item - * @code{ENOMEM} - There is not enough memory. - * @end itemize -=*/ -token_list_t * -ao_string_tokenize(char const * str) -{ - token_list_t * res = alloc_token_list(str); - ch_t * pzDest; - - /* - * Now copy each token into the output buffer. - */ - if (res == NULL) - return res; - - pzDest = (ch_t *)(res->tkn_list[0]); - res->tkn_ct = 0; - - do { - res->tkn_list[ res->tkn_ct++ ] = pzDest; - for (;;) { - int ch = (ch_t)*str; - if (IS_WHITESPACE_CHAR(ch)) { - found_white_space: - str = SPN_WHITESPACE_CHARS(str+1); - break; - } - - switch (ch) { - case '"': - copy_cooked(&pzDest, &str); - if (str == NULL) { - free(res); - errno = EINVAL; - return NULL; - } - if (IS_WHITESPACE_CHAR(*str)) - goto found_white_space; - break; - - case '\'': - copy_raw(&pzDest, &str); - if (str == NULL) { - free(res); - errno = EINVAL; - return NULL; - } - if (IS_WHITESPACE_CHAR(*str)) - goto found_white_space; - break; - - case NUL: - goto copy_done; - - default: - str++; - *(pzDest++) = (unsigned char)ch; - } - } copy_done:; - - /* - * NUL terminate the last token and see if we have any more tokens. - */ - *(pzDest++) = NUL; - } while (*str != NUL); - - res->tkn_list[ res->tkn_ct ] = NULL; - - return res; -} - -#ifdef TEST -#include -#include - -int -main(int argc, char ** argv) -{ - if (argc == 1) { - printf("USAGE: %s arg [ ... ]\n", *argv); - return 1; - } - while (--argc > 0) { - char * arg = *(++argv); - token_list_t * p = ao_string_tokenize(arg); - if (p == NULL) { - printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n", - arg, errno, strerror(errno)); - } else { - int ix = 0; - printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct); - do { - printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]); - } while (++ix < p->tkn_ct); - free(p); - } - } - return 0; -} -#endif - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/tokenize.c */ diff --git a/src/libopts/usage.c b/src/libopts/usage.c deleted file mode 100644 index 8df3591..0000000 --- a/src/libopts/usage.c +++ /dev/null @@ -1,1285 +0,0 @@ - -/* - * \file usage.c - * - * This module implements the default usage procedure for - * Automated Options. It may be overridden, of course. - * - * @addtogroup autoopts - * @{ - */ -/* - * Sort options: - --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \ - --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \ - --spac=2 --input=usage.c - */ - -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -#define GRAPH_CH(_ch) \ - ((((unsigned)_ch) <= 0x7E) && (((unsigned)_ch) > ' ')) - -/** - * Parse the option usage flags string. Any parsing problems yield - * a zero (no flags set) result. This function is internal to - * set_usage_flags(). - * - * @param[in] fnt Flag Name Table - maps a name to a mask - * @param[in] txt the text to process. If NULL, then - * getenv("AUTOOPTS_USAGE") is used. - * @returns a bit mask indicating which \a fnt entries were found. - */ -static unsigned int -parse_usage_flags(ao_flag_names_t const * fnt, char const * txt) -{ - unsigned int res = 0; - - /* - * The text may be passed in. If not, use the environment variable. - */ - if (txt == NULL) { - txt = getenv("AUTOOPTS_USAGE"); - if (txt == NULL) - return 0; - } - - txt = SPN_WHITESPACE_CHARS(txt); - if (*txt == NUL) - return 0; - - /* - * search the string for table entries. We must understand everything - * we see in the string, or we give up on it. - */ - for (;;) { - int ix = 0; - - for (;;) { - if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0) - break; - if (++ix >= AOUF_COUNT) - return 0; - } - - /* - * Make sure we have a full match. Look for whitespace, - * a comma, or a NUL byte. - */ - if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len])) - return 0; - - res |= 1U << ix; - txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len); - - switch (*txt) { - case NUL: - return res; - - case ',': - txt = SPN_WHITESPACE_CHARS(txt + 1); - /* Something must follow the comma */ - /* FALLTHROUGH */ - - default: - continue; - } - } -} - -/** - * Set option usage flags. Any parsing problems yield no changes to options. - * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE - * and \a OPTPROC_COMPUTE. - * - * @param[in] flg_txt text to parse. If NULL, then the AUTOOPTS_USAGE - * environment variable is parsed. - * @param[in,out] opts the program option descriptor - */ -static void -set_usage_flags(tOptions * opts, char const * flg_txt) -{ -# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n }, - static ao_flag_names_t const fn_table[AOUF_COUNT] = { - AOFLAG_TABLE - }; -# undef _aof_ - - /* - * the flag word holds a bit for each selected table entry. - */ - unsigned int flg = parse_usage_flags(fn_table, flg_txt); - if (flg == 0) return; - - /* - * Ensure we do not have conflicting selections - */ - { - static unsigned int const form_mask = - AOUF_gnu | AOUF_autoopts; - static unsigned int const misuse_mask = - AOUF_no_misuse_usage | AOUF_misuse_usage; - if ( ((flg & form_mask) == form_mask) - || ((flg & misuse_mask) == misuse_mask) ) - return; - } - - /* - * Now fiddle the fOptSet bits, based on settings. - * The OPTPROC_LONGOPT bit is immutable, thus if it is set, - * then fnm points to a mask off mask. - */ - { - ao_flag_names_t const * fnm = fn_table; - for (;;) { - if ((flg & 1) != 0) { - if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0) - opts->fOptSet &= fnm->fnm_mask; - else opts->fOptSet |= fnm->fnm_mask; - } - flg >>= 1; - if (flg == 0) - break; - fnm++; - } - } -} - -/* - * Figure out if we should try to format usage text sort-of like - * the way many GNU programs do. - */ -static inline bool -do_gnu_usage(tOptions * pOpts) -{ - return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false; -} - -/* - * Figure out if we should try to format usage text sort-of like - * the way many GNU programs do. - */ -static inline bool -skip_misuse_usage(tOptions * pOpts) -{ - return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false; -} - - -/*=export_func optionOnlyUsage - * - * what: Print usage text for just the options - * arg: + tOptions * + pOpts + program options descriptor + - * arg: + int + ex_code + exit code for calling exit(3) + - * - * doc: - * This routine will print only the usage for each option. - * This function may be used when the emitted usage must incorporate - * information not available to AutoOpts. -=*/ -void -optionOnlyUsage(tOptions * pOpts, int ex_code) -{ - char const * pOptTitle = NULL; - - set_usage_flags(pOpts, NULL); - if ((ex_code != EXIT_SUCCESS) && - skip_misuse_usage(pOpts)) - return; - - /* - * Determine which header and which option formatting strings to use - */ - if (do_gnu_usage(pOpts)) - (void)setGnuOptFmts(pOpts, &pOptTitle); - else - (void)setStdOptFmts(pOpts, &pOptTitle); - - prt_opt_usage(pOpts, ex_code, pOptTitle); - - fflush(option_usage_fp); - if (ferror(option_usage_fp) != 0) - fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr) - ? zstderr_name : zstdout_name); -} - -/** - * Print a message suggesting how to get help. - * - * @param[in] opts the program options - */ -static void -print_offer_usage(tOptions * opts) -{ - char help[24]; - - if (HAS_opt_usage_t(opts)) { - int ix = opts->presetOptCt; - tOptDesc * od = opts->pOptDesc + ix; - while (od->optUsage != AOUSE_HELP) { - if (++ix >= opts->optCt) - ao_bug(zmissing_help_msg); - od++; - } - switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { - case OPTPROC_SHORTOPT: - help[0] = '-'; - help[1] = od->optValue; - help[2] = NUL; - break; - - case OPTPROC_LONGOPT: - case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): - help[0] = help[1] = '-'; - strncpy(help + 2, od->pz_Name, 20); - break; - - case 0: - strncpy(help, od->pz_Name, 20); - break; - } - - } else { - switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { - case OPTPROC_SHORTOPT: - strcpy(help, "-h"); - break; - - case OPTPROC_LONGOPT: - case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): - strcpy(help, "--help"); - break; - - case 0: - strcpy(help, "help"); - break; - } - } - - fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help); -} - -/** - * Print information about each option. - * - * @param[in] opts the program options - * @param[in] exit_code whether or not there was a usage error reported. - * used to select full usage versus abbreviated. - */ -static void -print_usage_details(tOptions * opts, int exit_code) -{ - { - char const * pOptTitle = NULL; - int flen; - - /* - * Determine which header and which option formatting strings to use - */ - if (do_gnu_usage(opts)) { - flen = setGnuOptFmts(opts, &pOptTitle); - sprintf(line_fmt_buf, zFmtFmt, flen); - fputc(NL, option_usage_fp); - - } else { - flen = setStdOptFmts(opts, &pOptTitle); - sprintf(line_fmt_buf, zFmtFmt, flen); - - /* - * When we exit with EXIT_SUCCESS and the first option is a doc - * option, we do *NOT* want to emit the column headers. - * Otherwise, we do. - */ - if ( (exit_code != EXIT_SUCCESS) - || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) ) - - fputs(pOptTitle, option_usage_fp); - } - - flen = 4 - ((flen + 15) / 8); - if (flen > 0) - tab_skip_ct = flen; - prt_opt_usage(opts, exit_code, pOptTitle); - } - - /* - * Describe the mechanics of denoting the options - */ - switch (opts->fOptSet & OPTPROC_L_N_S) { - case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break; - case OPTPROC_SHORTOPT: break; - case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break; - case 0: fputs(zOptsOnly, option_usage_fp); break; - } - - if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0) - fputs(zNumberOpt, option_usage_fp); - - if ((opts->fOptSet & OPTPROC_REORDER) != 0) - fputs(zReorder, option_usage_fp); - - if (opts->pzExplain != NULL) - fputs(opts->pzExplain, option_usage_fp); - - /* - * IF the user is asking for help (thus exiting with SUCCESS), - * THEN see what additional information we can provide. - */ - if (exit_code == EXIT_SUCCESS) - prt_prog_detail(opts); - - /* - * Give bug notification preference to the packager information - */ - if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) - fputs(opts->pzPackager, option_usage_fp); - - else if (opts->pzBugAddr != NULL) - fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr); - - fflush(option_usage_fp); - - if (ferror(option_usage_fp) != 0) - fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr) - ? zstderr_name : zstdout_name); -} - -static void -print_one_paragraph(char const * text, bool plain, FILE * fp) -{ - if (plain) { -#ifdef ENABLE_NLS -#ifdef HAVE_LIBINTL_H -#ifdef DEBUG_ENABLED -#undef gettext -#endif - char * buf = dgettext("libopts", text); - if (buf == text) - text = gettext(text); -#endif /* HAVE_LIBINTL_H */ -#endif /* ENABLE_NLS */ - fputs(text, fp); - } - - else { - char const * t = optionQuoteString(text, LINE_SPLICE); - fprintf(fp, PUTS_FMT, t); - AGFREE(t); - } -} - -/*=export_func optionPrintParagraphs - * private: - * - * what: Print a paragraph of usage text - * arg: + char const * + text + a block of text that has bee i18n-ed + - * arg: + bool + plain + false -> wrap text in fputs() + - * arg: + FILE * + fp + the stream file pointer for output + - * - * doc: - * This procedure is called in two contexts: when a full or short usage text - * has been provided for display, and when autogen is assembling a list of - * translatable texts in the optmain.tlib template. In the former case, \a - * plain is set to \a true, otherwise \a false. - * - * Anything less than 256 characters in size is printed as a single unit. - * Otherwise, paragraphs are detected. A paragraph break is defined as just - * before a non-empty line preceded by two newlines or a line that starts - * with at least one space character but fewer than 8 space characters. - * Lines indented with tabs or more than 7 spaces are considered continuation - * lines. - * - * If 'plain' is true, we are emitting text for a user to see. So, if it is - * true and NLS is not enabled, then just write the whole thing at once. -=*/ -void -optionPrintParagraphs(char const * text, bool plain, FILE * fp) -{ - size_t len = strlen(text); - char * buf; -#ifndef ENABLE_NLS - if (plain || (len < 256)) -#else - if (len < 256) -#endif - { - print_one_paragraph(text, plain, fp); - return; - } - - AGDUPSTR(buf, text, "ppara"); - text = buf; - - for (;;) { - char * scan; - - if (len < 256) { - done: - print_one_paragraph(buf, plain, fp); - break; - } - scan = buf; - - try_longer: - scan = strchr(scan, NL); - if (scan == NULL) - goto done; - - if ((scan - buf) < 40) { - scan++; - goto try_longer; - } - - scan++; - if ((! isspace((int)*scan)) || (*scan == HT)) - /* - * line starts with tab or non-whitespace --> continuation - */ - goto try_longer; - - if (*scan == NL) { - /* - * Double newline -> paragraph break - * Include all newlines in current paragraph. - */ - while (*++scan == NL) /*continue*/; - - } else { - char * p = scan; - int sp_ct = 0; - - while (*p == ' ') { - if (++sp_ct >= 8) { - /* - * Too many spaces --> continuation line - */ - scan = p; - goto try_longer; - } - p++; - } - } - - /* - * "scan" points to the first character of a paragraph or the - * terminating NUL byte. - */ - { - char svch = *scan; - *scan = NUL; - print_one_paragraph(buf, plain, fp); - len -= scan - buf; - if (len <= 0) - break; - *scan = svch; - buf = scan; - } - } - AGFREE(text); -} - -/*=export_func optionUsage - * private: - * - * what: Print usage text - * arg: + tOptions * + opts + program options descriptor + - * arg: + int + exitCode + exit code for calling exit(3) + - * - * doc: - * This routine will print usage in both GNU-standard and AutoOpts-expanded - * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will - * over-ride this, providing the value of it is set to either "gnu" or - * "autoopts". This routine will @strong{not} return. - * - * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to - * to stdout and the actual exit code will be "EXIT_SUCCESS". -=*/ -noreturn void -optionUsage(tOptions * opts, int usage_exit_code) -{ - int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE) - ? EXIT_SUCCESS : usage_exit_code; - - displayEnum = false; - set_usage_flags(opts, NULL); - - /* - * Paged usage will preset option_usage_fp to an output file. - * If it hasn't already been set, then set it to standard output - * on successful exit (help was requested), otherwise error out. - * - * Test the version before obtaining pzFullUsage or pzShortUsage. - * These fields do not exist before revision 30. - */ - { - char const * pz; - - if (exit_code == EXIT_SUCCESS) { - pz = (opts->structVersion >= 30 * 4096) - ? opts->pzFullUsage : NULL; - - if (option_usage_fp == NULL) - option_usage_fp = print_exit ? stderr : stdout; - - } else { - pz = (opts->structVersion >= 30 * 4096) - ? opts->pzShortUsage : NULL; - - if (option_usage_fp == NULL) - option_usage_fp = stderr; - } - - if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) { - if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) - optionPrintParagraphs(pz, true, option_usage_fp); - else - fputs(pz, option_usage_fp); - goto flush_and_exit; - } - } - - fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName); - - if ((exit_code == EXIT_SUCCESS) || - (! skip_misuse_usage(opts))) - - print_usage_details(opts, usage_exit_code); - else - print_offer_usage(opts); - - flush_and_exit: - fflush(option_usage_fp); - if (ferror(option_usage_fp) != 0) - fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout) - ? zstdout_name : zstderr_name); - - option_exits(exit_code); -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * PER OPTION TYPE USAGE INFORMATION - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** - * print option conflicts. - * - * @param opts the program option descriptor - * @param od the option descriptor - */ -static void -prt_conflicts(tOptions * opts, tOptDesc * od) -{ - const int * opt_no; - fputs(zTabHyp + tab_skip_ct, option_usage_fp); - - /* - * REQUIRED: - */ - if (od->pOptMust != NULL) { - opt_no = od->pOptMust; - - if (opt_no[1] == NO_EQUIVALENT) { - fprintf(option_usage_fp, zReqOne, - opts->pOptDesc[*opt_no].pz_Name); - } else { - fputs(zReqThese, option_usage_fp); - for (;;) { - fprintf(option_usage_fp, zTabout + tab_skip_ct, - opts->pOptDesc[*opt_no].pz_Name); - if (*++opt_no == NO_EQUIVALENT) - break; - } - } - - if (od->pOptCant != NULL) - fputs(zTabHypAnd + tab_skip_ct, option_usage_fp); - } - - /* - * CONFLICTS: - */ - if (od->pOptCant == NULL) - return; - - opt_no = od->pOptCant; - - if (opt_no[1] == NO_EQUIVALENT) { - fprintf(option_usage_fp, zProhibOne, - opts->pOptDesc[*opt_no].pz_Name); - return; - } - - fputs(zProhib, option_usage_fp); - for (;;) { - fprintf(option_usage_fp, zTabout + tab_skip_ct, - opts->pOptDesc[*opt_no].pz_Name); - if (*++opt_no == NO_EQUIVALENT) - break; - } -} - -/** - * Print the usage information for a single vendor option. - * - * @param[in] opts the program option descriptor - * @param[in] od the option descriptor - * @param[in] argtp names of the option argument types - * @param[in] usefmt format for primary usage line - */ -static void -prt_one_vendor(tOptions * opts, tOptDesc * od, - arg_types_t * argtp, char const * usefmt) -{ - prt_preamble(opts, od, argtp); - - { - char z[ 80 ]; - char const * pzArgType; - - /* - * Determine the argument type string first on its usage, then, - * when the option argument is required, base the type string on the - * argument type. - */ - if (od->fOptState & OPTST_ARG_OPTIONAL) { - pzArgType = argtp->pzOpt; - - } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_NONE: pzArgType = argtp->pzNo; break; - case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey; break; - case OPARG_TYPE_FILE: pzArgType = argtp->pzFile; break; - case OPARG_TYPE_MEMBERSHIP: pzArgType = argtp->pzKeyL; break; - case OPARG_TYPE_BOOLEAN: pzArgType = argtp->pzBool; break; - case OPARG_TYPE_NUMERIC: pzArgType = argtp->pzNum; break; - case OPARG_TYPE_HIERARCHY: pzArgType = argtp->pzNest; break; - case OPARG_TYPE_STRING: pzArgType = argtp->pzStr; break; - case OPARG_TYPE_TIME: pzArgType = argtp->pzTime; break; - default: goto bogus_desc; - } - - pzArgType = SPN_WHITESPACE_CHARS(pzArgType); - if (*pzArgType == NUL) - snprintf(z, sizeof(z), "%s", od->pz_Name); - else - snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType); - fprintf(option_usage_fp, usefmt, z, od->pzText); - - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_ENUMERATION: - case OPARG_TYPE_MEMBERSHIP: - displayEnum = (od->pOptProc != NULL) ? true : displayEnum; - } - } - - return; - - bogus_desc: - fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); - ao_bug(zbad_arg_type_msg); -} - -/** - * Print the long options processed with "-W". These options will be the - * ones that do *not* have flag characters. - * - * @param opts the program option descriptor - * @param title the title for the options - */ -static void -prt_vendor_opts(tOptions * opts, char const * title) -{ - static unsigned int const not_vended_mask = - OPTST_NO_USAGE_MASK | OPTST_DOCUMENT; - - static char const vfmtfmt[] = "%%-%us %%s\n"; - char vfmt[sizeof(vfmtfmt)]; - - /* - * Only handle client specified options. The "vendor option" follows - * "presetOptCt", so we won't loop/recurse indefinitely. - */ - int ct = opts->presetOptCt; - tOptDesc * od = opts->pOptDesc; - fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre); - - { - size_t nmlen = 0; - do { - size_t l; - if ( ((od->fOptState & not_vended_mask) != 0) - || GRAPH_CH(od->optValue)) - continue; - - l = strlen(od->pz_Name); - if (l > nmlen) nmlen = l; - } while (od++, (--ct > 0)); - - snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4); - } - - if (tab_skip_ct > 0) - tab_skip_ct--; - - ct = opts->presetOptCt; - od = opts->pOptDesc; - - do { - if ( ((od->fOptState & not_vended_mask) != 0) - || GRAPH_CH(od->optValue)) - continue; - - prt_one_vendor(opts, od, &argTypes, vfmt); - prt_extd_usage(opts, od, title); - - } while (od++, (--ct > 0)); - - /* no need to restore "tab_skip_ct" - options are done now */ -} - -/** - * Print extended usage. Usage/help was requested. - * - * @param opts the program option descriptor - * @param od the option descriptor - * @param title the title for the options - */ -static void -prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title) -{ - if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) - && (od->optActualValue == VENDOR_OPTION_VALUE)) { - prt_vendor_opts(opts, title); - return; - } - - /* - * IF there are option conflicts or dependencies, - * THEN print them here. - */ - if ((od->pOptMust != NULL) || (od->pOptCant != NULL)) - prt_conflicts(opts, od); - - /* - * IF there is a disablement string - * THEN print the disablement info - */ - if (od->pz_DisableName != NULL ) - fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName); - - /* - * Check for argument types that have callbacks with magical properties - */ - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_NUMERIC: - /* - * IF the numeric option has a special callback, - * THEN call it, requesting the range or other special info - */ - if ( (od->pOptProc != NULL) - && (od->pOptProc != optionNumericVal) ) { - (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); - } - break; - - case OPARG_TYPE_FILE: - (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); - break; - } - - /* - * IF the option defaults to being enabled, - * THEN print that out - */ - if (od->fOptState & OPTST_INITENABLED) - fputs(zEnab + tab_skip_ct, option_usage_fp); - - /* - * IF the option is in an equivalence class - * AND not the designated lead - * THEN print equivalence and leave it at that. - */ - if ( (od->optEquivIndex != NO_EQUIVALENT) - && (od->optEquivIndex != od->optActualIndex ) ) { - fprintf(option_usage_fp, zalt_opt + tab_skip_ct, - opts->pOptDesc[ od->optEquivIndex ].pz_Name); - return; - } - - /* - * IF this particular option can NOT be preset - * AND some form of presetting IS allowed, - * AND it is not an auto-managed option (e.g. --help, et al.) - * THEN advise that this option may not be preset. - */ - if ( ((od->fOptState & OPTST_NO_INIT) != 0) - && ( (opts->papzHomeList != NULL) - || (opts->pzPROGNAME != NULL) - ) - && (od->optIndex < opts->presetOptCt) - ) - - fputs(zNoPreset + tab_skip_ct, option_usage_fp); - - /* - * Print the appearance requirements. - */ - if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP) - fputs(zMembers + tab_skip_ct, option_usage_fp); - - else switch (od->optMinCt) { - case 1: - case 0: - switch (od->optMaxCt) { - case 0: fputs(zPreset + tab_skip_ct, option_usage_fp); break; - case NOLIMIT: fputs(zNoLim + tab_skip_ct, option_usage_fp); break; - case 1: break; - /* - * IF the max is more than one but limited, print "UP TO" message - */ - default: - fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break; - } - break; - - default: - /* - * More than one is required. Print the range. - */ - fprintf(option_usage_fp, zMust + tab_skip_ct, - od->optMinCt, od->optMaxCt); - } - - if ( NAMED_OPTS(opts) - && (opts->specOptIdx.default_opt == od->optIndex)) - fputs(zDefaultOpt + tab_skip_ct, option_usage_fp); -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** - * Figure out where all the initialization files might live. This requires - * translating some environment variables and testing to see if a name is a - * directory or a file. It's squishy, but important to tell users how to - * find these files. - * - * @param[in] papz search path - * @param[out] ini_file an output buffer of AG_PATH_MAX+1 bytes - * @param[in] path_nm the name of the file we're hunting for - */ -static void -prt_ini_list(char const * const * papz, char const * ini_file, - char const * path_nm) -{ - char pth_buf[AG_PATH_MAX+1]; - - fputs(zPresetIntro, option_usage_fp); - - for (;;) { - char const * path = *(papz++); - char const * nm_buf = pth_buf; - - if (path == NULL) - break; - - /* - * Ignore any invalid paths - */ - if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm)) - nm_buf = path; - - /* - * Expand paths that are relative to the executable or installation - * directories. Leave alone paths that use environment variables. - */ - else if ((*path == '$') - && ((path[1] == '$') || (path[1] == '@'))) - path = nm_buf; - - /* - * Print the name of the "homerc" file. If the "rcfile" name is - * not empty, we may or may not print that, too... - */ - fprintf(option_usage_fp, zPathFmt, path); - if (*ini_file != NUL) { - struct stat sb; - - /* - * IF the "homerc" file is a directory, - * then append the "rcfile" name. - */ - if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) { - fputc(DIRCH, option_usage_fp); - fputs(ini_file, option_usage_fp); - } - } - - fputc(NL, option_usage_fp); - } -} - -/** - * Print the usage line preamble text - * - * @param opts the program option descriptor - * @param od the option descriptor - * @param at names of the option argument types - */ -static void -prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at) -{ - /* - * Flag prefix: IF no flags at all, then omit it. If not printable - * (not allowed for this option), then blank, else print it. - * Follow it with a comma if we are doing GNU usage and long - * opts are to be printed too. - */ - if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) - fputs(at->pzSpc, option_usage_fp); - - else if (! GRAPH_CH(od->optValue)) { - if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) - == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) - fputc(' ', option_usage_fp); - fputs(at->pzNoF, option_usage_fp); - - } else { - fprintf(option_usage_fp, " -%c", od->optValue); - if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) - == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) - fputs(", ", option_usage_fp); - } -} - -/** - * Print the usage information for a single option. - * - * @param opts the program option descriptor - * @param od the option descriptor - * @param at names of the option argument types - */ -static void -prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at) -{ - prt_preamble(opts, od, at); - - { - char z[80]; - char const * atyp; - - /* - * Determine the argument type string first on its usage, then, - * when the option argument is required, base the type string on the - * argument type. - */ - if (od->fOptState & OPTST_ARG_OPTIONAL) { - atyp = at->pzOpt; - - } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_NONE: atyp = at->pzNo; break; - case OPARG_TYPE_ENUMERATION: atyp = at->pzKey; break; - case OPARG_TYPE_FILE: atyp = at->pzFile; break; - case OPARG_TYPE_MEMBERSHIP: atyp = at->pzKeyL; break; - case OPARG_TYPE_BOOLEAN: atyp = at->pzBool; break; - case OPARG_TYPE_NUMERIC: atyp = at->pzNum; break; - case OPARG_TYPE_HIERARCHY: atyp = at->pzNest; break; - case OPARG_TYPE_STRING: atyp = at->pzStr; break; - case OPARG_TYPE_TIME: atyp = at->pzTime; break; - default: goto bogus_desc; - } - -#ifdef _WIN32 - if (at->pzOptFmt == zGnuOptFmt) - snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp); - else if (at->pzOptFmt == zGnuOptFmt + 2) - snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp); - else -#endif - snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name, - (od->optMinCt != 0) ? at->pzReq : at->pzOpt); - - fprintf(option_usage_fp, line_fmt_buf, z, od->pzText); - - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_ENUMERATION: - case OPARG_TYPE_MEMBERSHIP: - displayEnum = (od->pOptProc != NULL) ? true : displayEnum; - } - } - - return; - - bogus_desc: - fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); - option_exits(EX_SOFTWARE); -} - -/** - * Print out the usage information for just the options. - */ -static void -prt_opt_usage(tOptions * opts, int ex_code, char const * title) -{ - int ct = opts->optCt; - int optNo = 0; - tOptDesc * od = opts->pOptDesc; - int docCt = 0; - - do { - /* - * no usage --> disallowed on command line (OPTST_NO_COMMAND), or - * deprecated -- strongly discouraged (OPTST_DEPRECATED), or - * compiled out of current object code (OPTST_OMITTED) - */ - if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) { - - /* - * IF this is a compiled-out option - * *AND* usage was requested with "omitted-usage" - * *AND* this is NOT abbreviated usage - * THEN display this option. - */ - if ( (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) - && (od->pz_Name != NULL) - && (ex_code == EXIT_SUCCESS)) { - - char const * why_pz = - (od->pzText == NULL) ? zDisabledWhy : od->pzText; - prt_preamble(opts, od, &argTypes); - fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz); - } - - continue; - } - - if ((od->fOptState & OPTST_DOCUMENT) != 0) { - if (ex_code == EXIT_SUCCESS) { - fprintf(option_usage_fp, argTypes.pzBrk, od->pzText, - title); - docCt++; - } - - continue; - } - - /* Skip name only options when we have a vendor option */ - if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) - && (! GRAPH_CH(od->optValue))) - continue; - - /* - * IF this is the first auto-opt maintained option - * *AND* we are doing a full help - * *AND* there are documentation options - * *AND* the last one was not a doc option, - * THEN document that the remaining options are not user opts - */ - if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) { - if (opts->presetOptCt == optNo) { - if ((od[-1].fOptState & OPTST_DOCUMENT) == 0) - fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title); - - } else if ((ct == 1) && - (opts->fOptSet & OPTPROC_VENDOR_OPT)) - fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title); - } - - prt_one_usage(opts, od, &argTypes); - - /* - * IF we were invoked because of the --help option, - * THEN print all the extra info - */ - if (ex_code == EXIT_SUCCESS) - prt_extd_usage(opts, od, title); - - } while (od++, optNo++, (--ct > 0)); - - fputc(NL, option_usage_fp); -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/** - * Print program details. - * @param[in] opts the program option descriptor - */ -static void -prt_prog_detail(tOptions * opts) -{ - bool need_intro = (opts->papzHomeList == NULL); - - /* - * Display all the places we look for config files, if we have - * a list of directories to search. - */ - if (! need_intro) - prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath); - - /* - * Let the user know about environment variable settings - */ - if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) { - if (need_intro) - fputs(zPresetIntro, option_usage_fp); - - fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME); - } - - /* - * IF we found an enumeration, - * THEN hunt for it again. Call the handler proc with a NULL - * option struct pointer. That tells it to display the keywords. - */ - if (displayEnum) { - int ct = opts->optCt; - int optNo = 0; - tOptDesc * od = opts->pOptDesc; - - fputc(NL, option_usage_fp); - fflush(option_usage_fp); - do { - switch (OPTST_GET_ARGTYPE(od->fOptState)) { - case OPARG_TYPE_ENUMERATION: - case OPARG_TYPE_MEMBERSHIP: - (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); - } - } while (od++, optNo++, (--ct > 0)); - } - - /* - * If there is a detail string, now is the time for that. - */ - if (opts->pzDetail != NULL) - fputs(opts->pzDetail, option_usage_fp); -} - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - * OPTION LINE FORMATTING SETUP - * - * The "OptFmt" formats receive three arguments: - * 1. the type of the option's argument - * 2. the long name of the option - * 3. "YES" or "no ", depending on whether or not the option must appear - * on the command line. - * These formats are used immediately after the option flag (if used) has - * been printed. - * - * Set up the formatting for GNU-style output - */ -static int -setGnuOptFmts(tOptions * opts, char const ** ptxt) -{ - static char const zOneSpace[] = " "; - int flen = 22; - *ptxt = zNoRq_ShrtTtl; - - argTypes.pzStr = zGnuStrArg; - argTypes.pzReq = zOneSpace; - argTypes.pzNum = zGnuNumArg; - argTypes.pzKey = zGnuKeyArg; - argTypes.pzKeyL = zGnuKeyLArg; - argTypes.pzTime = zGnuTimeArg; - argTypes.pzFile = zGnuFileArg; - argTypes.pzBool = zGnuBoolArg; - argTypes.pzNest = zGnuNestArg; - argTypes.pzOpt = zGnuOptArg; - argTypes.pzNo = zOneSpace; - argTypes.pzBrk = zGnuBreak; - argTypes.pzNoF = zSixSpaces; - argTypes.pzSpc = zThreeSpaces; - - switch (opts->fOptSet & OPTPROC_L_N_S) { - case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break; - case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break; - case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break; - case OPTPROC_SHORTOPT: - argTypes.pzOptFmt = zShrtGnuOptFmt; - zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' '; - argTypes.pzOpt = " [arg]"; - flen = 8; - break; - } - - return flen; -} - - -/* - * Standard (AutoOpts normal) option line formatting - */ -static int -setStdOptFmts(tOptions * opts, char const ** ptxt) -{ - int flen = 0; - - argTypes.pzStr = zStdStrArg; - argTypes.pzReq = zStdReqArg; - argTypes.pzNum = zStdNumArg; - argTypes.pzKey = zStdKeyArg; - argTypes.pzKeyL = zStdKeyLArg; - argTypes.pzTime = zStdTimeArg; - argTypes.pzFile = zStdFileArg; - argTypes.pzBool = zStdBoolArg; - argTypes.pzNest = zStdNestArg; - argTypes.pzOpt = zStdOptArg; - argTypes.pzNo = zStdNoArg; - argTypes.pzBrk = zStdBreak; - argTypes.pzNoF = zFiveSpaces; - argTypes.pzSpc = zTwoSpaces; - - switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) { - case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT): - *ptxt = zNoRq_ShrtTtl; - argTypes.pzOptFmt = zNrmOptFmt; - flen = 19; - break; - - case OPTPROC_NO_REQ_OPT: - *ptxt = zNoRq_NoShrtTtl; - argTypes.pzOptFmt = zNrmOptFmt; - flen = 19; - break; - - case OPTPROC_SHORTOPT: - *ptxt = zReq_ShrtTtl; - argTypes.pzOptFmt = zReqOptFmt; - flen = 24; - break; - - case 0: - *ptxt = zReq_NoShrtTtl; - argTypes.pzOptFmt = zReqOptFmt; - flen = 24; - } - - return flen; -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/usage.c */ diff --git a/src/libopts/version.c b/src/libopts/version.c deleted file mode 100644 index cd46be3..0000000 --- a/src/libopts/version.c +++ /dev/null @@ -1,240 +0,0 @@ - -/** \file version.c - * - * This module implements the default usage procedure for - * Automated Options. It may be overridden, of course. - * - * @addtogroup autoopts - * @{ - */ -/* - * This file is part of AutoOpts, a companion to AutoGen. - * AutoOpts is free software. - * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved - * - * AutoOpts is available under any one of two licenses. The license - * in use must be one of these two and the choice is under the control - * of the user of the license. - * - * The GNU Lesser General Public License, version 3 or later - * See the files "COPYING.lgplv3" and "COPYING.gplv3" - * - * The Modified Berkeley Software Distribution License - * See the file "COPYING.mbsd" - * - * These files have the following sha256 sums: - * - * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 - * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 - * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd - */ - -/*=export_func optionVersion - * - * what: return the compiled AutoOpts version number - * ret_type: char const * - * ret_desc: the version string in constant memory - * doc: - * Returns the full version string compiled into the library. - * The returned string cannot be modified. -=*/ -char const * -optionVersion(void) -{ - static char const ver[] = OPTIONS_DOTTED_VERSION; - return ver; -} - -static void -emit_first_line( - FILE * fp, char const * alt1, char const * alt2, char const * alt3) -{ - char const * p = (alt1 != NULL) ? alt1 : ((alt2 != NULL) ? alt2 : alt3); - char const * e; - if (p == NULL) - return; - e = strchr(p, NL); - if (e == NULL) - fputs(p, fp); - else - fwrite(p, 1, (e - p), fp); - fputc(NL, fp); -} - -/** - * Select among various ways to emit version information. - * - * @param[in] o the option descriptor - * @param[in] fp the output stream - */ -static void -emit_simple_ver(tOptions * o, FILE * fp) -{ - emit_first_line(fp, o->pzFullVersion, o->pzCopyright, o->pzUsageTitle); -} - -/** - * print the version with a copyright notice. - * - * @param[in] o the option descriptor - * @param[in] fp the output stream - */ -static void -emit_copy_full(tOptions * o, FILE * fp) -{ - if (o->pzCopyright != NULL) - fputs(o->pzCopyright, fp); - - else if (o->pzFullVersion != NULL) - fputs(o->pzFullVersion, fp); - - else - emit_first_line(fp, o->pzUsageTitle, NULL, NULL); - - if (HAS_pzPkgDataDir(o) && (o->pzPackager != NULL)) { - fputc(NL, fp); - fputs(o->pzPackager, fp); - - } else if (o->pzBugAddr != NULL) { - fputc(NL, fp); - fprintf(fp, zPlsSendBugs, o->pzBugAddr); - } -} - -/** - * print the version and any copyright notice. - * The version with a full copyright and additional notes. - * - * @param[in] opts the option descriptor - * @param[in] fp the output stream - */ -static void -emit_copy_note(tOptions * opts, FILE * fp) -{ - if (opts->pzCopyright != NULL) - fputs(opts->pzCopyright, fp); - - if (opts->pzCopyNotice != NULL) - fputs(opts->pzCopyNotice, fp); - - fputc(NL, fp); - fprintf(fp, zao_ver_fmt, optionVersion()); - - if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) { - fputc(NL, fp); - fputs(opts->pzPackager, fp); - - } else if (opts->pzBugAddr != NULL) { - fputc(NL, fp); - fprintf(fp, zPlsSendBugs, opts->pzBugAddr); - } -} - -/** - * Handle the version printing. We must see how much information - * is being requested and select the correct printing routine. - */ -static void -print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit) -{ - char ch; - - if (opts <= OPTPROC_EMIT_LIMIT) - return; - - /* - * IF we have an argument for this option, use it - * Otherwise, default to version only or copyright note, - * depending on whether the layout is GNU standard form or not. - */ - if ( (od->fOptState & OPTST_ARG_OPTIONAL) - && (od->optArg.argString != NULL) - && (od->optArg.argString[0] != NUL)) - - ch = od->optArg.argString[0]; - - else if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_STATIC) { - ch = od->optArg.argString[0]; - - } else { - set_usage_flags(opts, NULL); - ch = (opts->fOptSet & OPTPROC_GNUUSAGE) ? 'c' : 'v'; - } - - switch (ch) { - case NUL: /* arg provided, but empty */ - case 'v': case 'V': emit_simple_ver(opts, fp); break; - case 'c': case 'C': emit_copy_full( opts, fp); break; - case 'n': case 'N': emit_copy_note( opts, fp); break; - - default: - fprintf(stderr, zBadVerArg, ch); - option_exits(EXIT_FAILURE); - } - - fflush(fp); - if (ferror(fp)) - fserr_exit(opts->pzProgName, zwriting, - (fp == stdout) ? zstdout_name : zstderr_name); - - if (call_exit) - option_exits(EXIT_SUCCESS); -} - -/*=export_func optionPrintVersion - * - * what: Print the program version - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * This routine will print the version to stdout. -=*/ -void -optionPrintVersion(tOptions * opts, tOptDesc * od) -{ - print_ver(opts, od, print_exit ? stderr : stdout, true); -} - -/*=export_func optionPrintVersionAndReturn - * - * what: Print the program version - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * This routine will print the version to stdout and return - * instead of exiting. Please see the source for the - * @code{print_ver} funtion for details on selecting how - * verbose to be after this function returns. -=*/ -void -optionPrintVersionAndReturn(tOptions * opts, tOptDesc * od) -{ - print_ver(opts, od, print_exit ? stderr : stdout, false); -} - -/*=export_func optionVersionStderr - * private: - * - * what: Print the program version to stderr - * arg: + tOptions * + opts + program options descriptor + - * arg: + tOptDesc * + od + the descriptor for this arg + - * - * doc: - * This routine will print the version to stderr. -=*/ -void -optionVersionStderr(tOptions * opts, tOptDesc * od) -{ - print_ver(opts, od, stderr, true); -} - -/** @} - * - * Local Variables: - * mode: C - * c-file-style: "stroustrup" - * indent-tabs-mode: nil - * End: - * end of autoopts/version.c */ diff --git a/tests/system.prio b/tests/system.prio index ef69f6a..53baaf2 100644 --- a/tests/system.prio +++ b/tests/system.prio @@ -1,3 +1,4 @@ HELLO1=NORMAL HELLO2=NORMAL:+AES-128-CBC HELLO3=NONE:+VERS-TLS-ALL:-VERS-SSL3.0:+AEAD:+SHA1:+SHA256:+SHA384:+ECDHE-RSA:+ECDHE-ECDSA:+RSA:+DHE-RSA:+DHE-DSS:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-GCM:+CAMELLIA-256-CBC:+AES-128-GCM:+AES-128-CBC:+CAMELLIA-128-GCM:+CAMELLIA-128-CBC:+3DES-CBC:+SIGN-ALL:-SIGN-RSA-MD5:+CURVE-ALL:+COMP-NULL:%PROFILE_LOW +SYSTEM=NORMAL