Spaces:
Sleeping
Sleeping
import os | |
import json | |
import subprocess | |
from tempfile import NamedTemporaryFile | |
import gradio as gr | |
from huggingface_hub import InferenceClient | |
import wandb | |
import shutil | |
import sys | |
# 1. Initialize W&B (free tier) for basic logging | |
# non-interactive login | |
#api_key = os.getenv("WANDB_API_KEY") | |
#if api_key: | |
# wandb.login(key=api_key, relogin=True) | |
# wandb.init(project="dipesh-gen-ai-2025-personal", entity="dipesh-gen-ai-2025") | |
#else: | |
# disable wandb entirely if key missing | |
# wandb.init(mode="disabled") | |
key = os.getenv("WANDB_API_KEY") | |
if key: | |
wandb.login(key=key, relogin=True) | |
# Always run anonymously (no entity permission needed) | |
wandb.init( | |
project="misra-smart-fixer", | |
mode="online", | |
anonymous="must" | |
) | |
# 2. Hugging Face Inference Client (CPU-only, free quota) | |
HF_TOKEN = os.getenv("HF_API_TOKEN") | |
#client = InferenceClient(model="declare-lab/flan-alpaca-gpt4", token=HF_TOKEN) | |
client = InferenceClient(model="codellama/CodeLlama-7b-hf", token=HF_TOKEN) | |
def ensure_tool(name: str): | |
if shutil.which(name) is None: | |
print(f"Error: `{name}` not found. Please install it and retry.", file=sys.stderr) | |
sys.exit(1) | |
def run_cppcheck(source_code: str): | |
# Check for the code checker tool | |
ensure_tool("cppcheck") | |
ext = ".c" if source_code.endswith(".c") else ".cpp" | |
tf = NamedTemporaryFile(suffix=ext, delete=False) | |
print("ext" + ext) | |
tf.write(source_code.encode()) | |
tf.flush() | |
tf.close() | |
# Run Cppcheck with MISRA 2012 profile, JSON output | |
# cmd = [ | |
# "cppcheck", "--enable=all", | |
# "--std=c++17", "--language=c++", | |
# "--profile=misra-cpp-2012", | |
# "--template=json", tf.name | |
# ] | |
# select language/std/profile by extension | |
if tf.name.endswith(".c"): | |
lang_args = ["--std=c11", "--language=c", "--profile=misra-c-2012"] | |
print("misra-c-2012") | |
else: | |
lang_args = ["--std=c++17", "--language=c++", "--profile=misra-cpp-2012"] | |
print("misra-cpp-2012") | |
cmd = ["cppcheck", "--enable=all", *lang_args, "--template=json", tf.name] | |
res = subprocess.run(cmd, capture_output=True, text=True) | |
try: | |
issues = json.loads(res.stderr) | |
except json.JSONDecodeError: | |
issues = [] | |
return tf.name, issues | |
def build_prompt(filename: str, issues: list): | |
with open(filename) as f: | |
src = f.read() | |
if not issues: | |
return None | |
summary = "\n".join([ | |
f"- {item['message']} at line {item['line']}" | |
for item in issues | |
]) | |
# prompt = f""" | |
# You are a C++ expert. The code below may violate MISRA C++:2012 rules. | |
# Source code: | |
# Issues: | |
# {summary} | |
# …""" | |
# detect language from filename | |
rule_set = "MISRA C:2012" if filename.endswith(".c") else "MISRA C++:2012" | |
prompt = f""" | |
You are a { 'C expert' if filename.endswith('.c') else 'C++ expert' } specializing in {rule_set} compliance. | |
Here is the source file (`{filename}`): | |
``` | |
{src} | |
``` | |
The static analyzer reported the following violations: | |
{summary} | |
Produce a unified diff patch that fixes all violations. For each change, include a one‐sentence rationale referencing the violated rule number. | |
Only return the diff. No extra commentary. | |
""" | |
return prompt.strip() | |
def predict_patch(prompt: str): | |
response = client.text_generation(prompt, max_new_tokens=256) | |
patch = response.generated_text | |
wandb.log({"prompt": prompt, "patch": patch}) | |
return patch | |
def process_file(file_obj): | |
#src = file_obj.read().decode() | |
src = file_obj | |
print("Source file - ") | |
print(src) | |
fname, issues = run_cppcheck(src) | |
print("Source file issues - ") | |
print(fname) | |
print(issues) | |
prompt = build_prompt(fname, issues) | |
if prompt is None: | |
return "No MISRA violations found.", None | |
patch = predict_patch(prompt) | |
return "Patch generated below:", patch | |
# Gradio UI | |
iface = gr.Interface( | |
fn=process_file, | |
inputs=gr.File(file_types=[".c", ".cpp", ".h", ".hpp"]), | |
outputs=[gr.Text(), gr.Text()], | |
title="MISRA Smart Fixer", | |
description="Upload C/C++ code to auto-fix MISRA violations.", | |
allow_flagging="never" | |
) | |
if __name__ == "__main__": | |
iface.launch(server_name="0.0.0.0", server_port=7860) | |