Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script for Docstring generation #9

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 219 additions & 0 deletions src/applications/bmqtool/cbmq_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// Copyright 2016-2023 Bloomberg Finance L.P.
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// m_bmqtool_filelogger.cpp -*-C++-*-
#include <m_bmqtool_filelogger.h>

// BMQ
#include <bmqa_queueid.h>
#include <bmqt_correlationid.h>
#include <bmqt_messageguid.h>
#include <bmqt_sessioneventtype.h>
#include <bmqt_uri.h>

// MWC
#include <mwcu_blob.h>

// BDE
#include <ball_context.h>
#include <ball_recordstringformatter.h>
#include <bdlb_print.h>
#include <bdlbb_blob.h>
#include <bdls_processutil.h>
#include <bdlt_currenttime.h>
#include <bslmt_threadutil.h>
#include <bsls_assert.h>

namespace BloombergLP {
namespace m_bmqtool {

namespace {

const char k_LOG_SESSION_CATEGORY[] = "SESSION";
const char k_LOG_PUSH_CATEGORY[] = "PUSH";
const char k_LOG_ACK_CATEGORY[] = "ACK";
const char k_LOG_PUT_CATEGORY[] = "PUT";
const char k_LOG_CONFIRM_CATEGORY[] = "CONFIRM";

class LogRecord {
private:
ball::Record d_record;
ball::FileObserver2& d_out;
bsl::ostream d_os;

public:
LogRecord(ball::FileObserver2& out,
const char* category,
int severity = ball::Severity::INFO)
: d_record()
, d_out(out)
, d_os(init(d_record, category, severity))
{
}

~LogRecord()
{
d_out.publish(
d_record,
ball::Context(ball::Transmission::e_MANUAL_PUBLISH, 0, 1));
}

template <typename T>
friend LogRecord& operator<<(LogRecord& record, const T& value);

private:
static bdlsb::MemOutStreamBuf*
init(ball::Record& record, const char* category, int severity)
{
ball::RecordAttributes& attributes = record.fixedFields();

attributes.setTimestamp(bdlt::CurrentTime::utc());
attributes.setProcessID(bdls::ProcessUtil::getProcessId());
attributes.setThreadID(bslmt::ThreadUtil::selfIdAsUint64());
attributes.setCategory(category);
attributes.setSeverity(severity);
// attributes.setFileName(__FILE__);
// attributes.setLineNumber(__LINE__);

attributes.clearMessage();
return &attributes.messageStreamBuf();
}
};

template <typename T>
LogRecord& operator<<(LogRecord& record, const T& value)
{
record.d_os << value;
return record;
}
static void printSingleLine(LogRecord& record, const bdlbb::Blob& blob)
{
for (int i = 0; i < blob.numDataBuffers(); ++i) {
record << bslstl::StringRef(blob.buffer(i).data(),
mwcu::BlobUtil::bufferSize(blob, i));
}
}

}; // close unnamed namespace

// ================
// class FileLogger
// ================

FileLogger::FileLogger(const bsl::string& filePath,
bslma::Allocator* allocator)
: d_filePath(filePath)
, d_out(allocator)
{
// NOTHING
}

FileLogger::~FileLogger()
{
close();
}

bool FileLogger::open()
{
d_out.enableFileLogging(d_filePath.c_str());

d_out.setLogFileFunctor(
ball::RecordStringFormatter("\n%I %p:%t %s %c %m %u"));
return d_out.isFileLoggingEnabled();
}

void FileLogger::close()
{
d_out.disableFileLogging();
}

void FileLogger::writeSessionEvent(const bmqa::SessionEvent& event)
{
if (!isOpen()) {
// FileLogging is disabled.
return; // RETURN
}

LogRecord record(d_out, k_LOG_SESSION_CATEGORY);
record << event.type() << "|"; // session event type

if (event.type() == bmqt::SessionEventType::e_QUEUE_OPEN_RESULT ||
event.type() == bmqt::SessionEventType::e_QUEUE_REOPEN_RESULT ||
event.type() == bmqt::SessionEventType::e_QUEUE_CLOSE_RESULT) {
record << event.queueId().uri().asString(); // queueUri
}
}

void FileLogger::writeAckMessage(const bmqa::Message& message)
{
if (!isOpen()) {
// FileLogging is disabled.
return; // RETURN
}

LogRecord record(d_out, k_LOG_ACK_CATEGORY);
record << message.queueId().uri().asString() << "|" // QueueUri
<< message.correlationId() << "|" // CorrelationId
<< message.messageGUID() << "|" // MessageGUID
<< message.ackStatus() << "|"; // AckStatus
}

void FileLogger::writeConfirmMessage(const bmqa::Message& message)
{
if (!isOpen()) {
// FileLogging is disabled.
return; // RETURN
}

LogRecord record(d_out, k_LOG_CONFIRM_CATEGORY);
record << message.queueId().uri().asString() << "|" // QueueUri
<< message.messageGUID() << "|"; // MessageGUID
}

void FileLogger::writePushMessage(const bmqa::Message& message)
{
if (!isOpen()) {
// FileLogging is disabled.
return; // RETURN
}

LogRecord record(d_out, k_LOG_PUSH_CATEGORY);
record << message.queueId().uri().asString() << "|" // QueueUri
<< message.messageGUID() << "|"; // MessageGUID

bdlbb::Blob payload;
message.getData(&payload);
printSingleLine(record, payload); // Payload
}

void FileLogger::writePutMessage(const bmqa::Message& message)
{
if (!isOpen()) {
// FileLogging is disabled.
return; // RETURN
}

LogRecord record(d_out, k_LOG_PUT_CATEGORY);
record << message.queueId().uri().asString() << "|" // QueueUri
<< message.correlationId() << "|" // CorrelationId
<< message.messageGUID() << "|"; // MessageGUID

bdlbb::Blob payload;
message.getData(&payload);
printSingleLine(record, payload); // Payload
}

} // close package namespace
} // close enterprise namespace
40 changes: 40 additions & 0 deletions src/docstring_replace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os

bmqa_directory = "bmqa"
z_bmqa_directory = "z_bmqa"

for filename in os.listdir(bmqa_directory):
if filename.endswith(".h"):
with open(os.path.join(bmqa_directory, filename), "r") as bmqa_file:
lines = bmqa_file.readlines()
docstring_lines = []
copy_docstring = False
for line in lines:
if "@PURPOSE" in line:
docstring_lines.append(line)
copy_docstring = True
elif copy_docstring and line.strip() == "":
break
elif copy_docstring:
docstring_lines.append(line)

with open(os.path.join(z_bmqa_directory, "z_" + filename), "r+") as z_bmqa_file:
lines = z_bmqa_file.readlines()
z_bmqa_file.seek(0)
z_bmqa_file.truncate()
include_found = False
copied = False

for line in lines:
print("line:", line, end="")
if line.startswith("#include"):
z_bmqa_file.write(line)
z_bmqa_file.write("\n")
include_found = True
elif include_found and not copied:
z_bmqa_file.writelines(docstring_lines)
z_bmqa_file.write(line)
include_found = False
copied = True
else:
z_bmqa_file.write(line)
114 changes: 114 additions & 0 deletions src/function_comments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import re


non_functions = set(["if", "else if", "else", "for", "while", "do"])


def append_to_file(string, filename):
try:
with open(filename, 'a') as file:
file.write(string)
except IOError:
print("Error: Unable to append string to file.")


def extract_words(lines): #we need to change this function to find the keywords after '(' because of templated types such as <int, int>
# Regular expression to match words followed by ',' or ')'
# \b asserts position at a word boundary
# \w+ matches one or more word characters (a-z, A-Z, 0-9, _)
# (?=[,)]) is a positive lookahead to ensure the word is followed by ',' or ')'
pattern = r'\b\w+(?=[,)])'

extracted_words = set() # Use a set to avoid duplicate words

for line in lines:
matches = re.findall(pattern, line)
extracted_words.update(matches) # Add found words to the set

return list(extracted_words) # Convert set to list before returning


def process_cpp_file(file_path):
buffer = [] # to store lines temporarily
current_function = "" # to keep track of the current function
function_descriptors = {}

with open(file_path, 'r') as file:
for line in file:
line = line.strip() # remove leading/trailing whitespaces

# Clear buffer if line is '}' or empty
if line == '}' or line == '':
buffer.clear()
else:
buffer.append(line) # add line to buffer

# Update current_function if line contains '{'
if '{' in line:
previous_func = current_function
keyword_found = False
for buf_line in buffer:
if '(' in buf_line:
# Extract function name
func_name = buf_line.split('(')[0].split()[-1]
if func_name not in non_functions:
# print(current_function)
current_function = func_name
function_descriptors[current_function] = extract_words(
buffer)
break
else:
keyword_found = True
if previous_func == current_function and not keyword_found:
print(
f"Function name could not be extracted for buffer: {buffer}")
print(function_descriptors)
return function_descriptors

def write_commented_file(file_path, new_file_name, function_descriptors):
buffer = [] # to store lines temporarily
current_function = "" # to keep track of the current function
# print(fd['z_bmqt_CorrelationId__delete'])

with open(file_path, 'r') as file:
for line in file:
temp_line = line
line = line.strip() # remove leading/trailing whitespaces

# Clear buffer if line is '}' or empty
if line == '}' or line == '':
for p in buffer:
append_to_file(p, new_file_name)
append_to_file(temp_line, new_file_name)
buffer.clear()
else:
buffer.append(temp_line) # add line to buffer

# Update current_function if line contains '{'
if '{' in line:
previous_func = current_function
keyword_found = False
for buf_line in buffer:
if '(' in buf_line:
# Extract function name
func_name = buf_line.split('(')[0].split()[-1]
if func_name not in non_functions:
current_function = func_name
append_to_file(str(function_descriptors[current_function]), new_file_name)
break
else:
keyword_found = True
else:
append_to_file(buf_line, new_file_name)

if previous_func == current_function and not keyword_found:
print(
f"Function name could not be extracted for buffer: {buffer}")

# Example of how to use the function
file_path = 'test_file.cpp'
fd = process_cpp_file(file_path)
print("-----------------------------")
print(fd)
print()
write_commented_file(file_path, "output.cpp", fd)
Loading