diff --git a/src/Type.cc b/src/Type.cc index 67b0bb7be9..ae2d94046c 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1273,8 +1273,25 @@ void EnumType::AddName(const string& module_name, const char* name, bro_int_t va void EnumType::AddComment(const string& module_name, const char* name, const char* comment) { + if ( ! comment ) return; + string fullname = make_full_var_name(module_name.c_str(), name); - comments[copy_string(fullname.c_str())] = copy_string(comment); + + CommentMap::iterator it = comments.find(fullname.c_str()); + + if ( it == comments.end() ) + comments[copy_string(fullname.c_str())] = comment; + else + { + // append to current comments + size_t len = strlen(it->second) + strlen(comment) + 1; + char* s = new char[len]; + sprintf(s, "%s%s", it->second, comment); + s[len - 1] = '\0'; + delete [] it->second; + delete [] comment; + comments[fullname.c_str()] = s; + } } void EnumType::AddNameInternal(const string& module_name, const char* name, bro_int_t val, bool is_export) diff --git a/src/parse.y b/src/parse.y index a01f655ea4..e9ee044c50 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3,7 +3,7 @@ // See the file "COPYING" in the main distribution directory for copyright. %} -%expect 74 +%expect 81 %token TOK_ADD TOK_ADD_TO TOK_ADDR TOK_ALARM TOK_ANY %token TOK_ATENDIF TOK_ATELSE TOK_ATIF TOK_ATIFDEF TOK_ATIFNDEF @@ -116,6 +116,7 @@ bool resolving_global_ID = false; ID* func_id = 0; EnumType *cur_enum_type = 0; +const char* cur_enum_elem_id = 0; static void parser_new_enum (void) { @@ -582,10 +583,12 @@ opt_expr_list: { $$ = new ListExpr(); } ; +/* opt_comma: ',' | ; +*/ pattern: pattern '|' single_pattern @@ -607,17 +610,40 @@ single_pattern: ; enum_body: - enum_body_list opt_comma + enum_body_list opt_post_doc_list { $$ = cur_enum_type; + if ( generate_documentation ) + { + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $2); + cur_enum_elem_id = 0; + } + cur_enum_type = NULL; + } + | enum_body_list ',' opt_post_doc_list + { + $$ = cur_enum_type; + if ( generate_documentation ) + { + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $3); + cur_enum_elem_id = 0; + } cur_enum_type = NULL; } ; enum_body_list: - enum_body_elem /* No action */ - | enum_body_list ',' enum_body_elem /* no action */ - ; + enum_body_elem opt_post_doc_list + { + if ( generate_documentation ) + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $2); + } + | enum_body_list ',' opt_post_doc_list + { + if ( generate_documentation ) + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $3); + } enum_body_elem +; enum_body_elem: /* TODO: We could also define this as TOK_ID '=' expr, (or @@ -625,17 +651,23 @@ enum_body_elem: error messages if someboy tries to use constant variables as enumerator. */ - TOK_ID '=' TOK_CONSTANT + opt_doc_list TOK_ID '=' TOK_CONSTANT { - set_location(@1, @3); + set_location(@2, @4); assert(cur_enum_type); - if ( $3->Type()->Tag() != TYPE_COUNT ) + if ( $4->Type()->Tag() != TYPE_COUNT ) error("enumerator is not a count constant"); else - cur_enum_type->AddName(current_module, $1, $3->InternalUnsigned(), is_export); + cur_enum_type->AddName(current_module, $2, $4->InternalUnsigned(), is_export); + + if ( generate_documentation ) + { + cur_enum_elem_id = $2; + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $1); + } } - | TOK_ID '=' '-' TOK_CONSTANT + | opt_doc_list TOK_ID '=' '-' TOK_CONSTANT { /* We only accept counts as enumerator, but we want to return a nice error message if users triy to use a negative integer (will also @@ -644,11 +676,17 @@ enum_body_elem: error("enumerator is not a count constant"); } - | TOK_ID + | opt_doc_list TOK_ID { - set_location(@1); + set_location(@2); assert(cur_enum_type); - cur_enum_type->AddName(current_module, $1, is_export); + cur_enum_type->AddName(current_module, $2, is_export); + + if ( generate_documentation ) + { + cur_enum_elem_id = $2; + cur_enum_type->AddComment(current_module, cur_enum_elem_id, $1); + } } ; @@ -754,8 +792,9 @@ type: $$ = 0; } - | TOK_ENUM '{' { set_location(@1); parser_new_enum(); } enum_body '}' + | TOK_ENUM '{' { set_location(@1); parser_new_enum(); do_doc_token_start(); } enum_body '}' { + do_doc_token_stop(); set_location(@1, @5); $4->UpdateLocationEndInfo(@5); $$ = $4;