التآزر بين Graphviz ومعالج C / C ++

تتناول هذه المقالة كيفية استخدام أداة الرسم البياني Graphviz الشائعة بالتعاون مع المعالج المسبق C / C ++ (المشار إليه فيما يلي باسم المعالج المسبق).


النقطة الأساسية هي أن لغة الرسم البياني النقطي التي يستخدمها Graphviz مناسبة للمعالجة المسبقة في تركيبها. تصور ذلك من قبل المطورين. بفضل رؤيتهم ، يمكننا استخدام الميزات التالية عند وصف الرسوم البيانية (أقتبس من ويكيبيديا من الذاكرة):


  • استبدال الحروف والأشكال المقابلة بالحروف المكافئة "#" و "\" ؛
  • إزالة أحرف تغذية الخط الفرار ؛
  • استبدال الخط وحظر التعليقات بخطوط فارغة (مع إزالة المسافات وعلامات التبويب المحيطة) ؛
  • إدراج (تضمين) محتويات ملف تعسفي ( تضمين # ) ؛
  • استبدال الماكرو ( # تعريف ) ؛
  • الترجمة الشرطية ( #if ، #ifdef ، #elif ، #else ، #endif ) ؛

الآن سنوضح الفرص المفتوحة في الممارسة. كمثال ، خذ الرسم البياني من مقالتي على MediaStrimer2 ، في الشكل أدناه.



الرسم البياني كبير بما يكفي وإذا وصفته "على الجبهة" ، فسوف يستغرق الكثير من العمل اليدوي الخالي من الأخطاء. إذا نظرت عن كثب ، يمكنك عزل العناصر المتكررة باختلاف فقط في محتوى بعض الحقول. هذه هي الطريقة التي تبدو بها العقد في الرسم البياني م 1 ، م 2 ، م 2_1 ، م 2_2 ، م 3 ، م 4 . هؤلاء هم المرشحون الأوائل لاستخدام الميكنة الصغيرة باستخدام وحدات الماكرو. إنشاء ملف رأس لملف النقطة الرئيسي لدينا. دعنا نسميها شائعة. النقطة :


//  common.dot       .

#define Q(x) #x         //    ""   .

#define QUOTE(x) Q(x)   //   ""    .

//         mblk_t.
//       . 
#define msg_staff \
   <p> *prev \
  |<n> *next \
  |<c> *cont  \
  |<d> *data \
  | other\nstuff

//        mblk_t.
#define msg(name, ... ) \
name[xlabel=mblk_t label=QUOTE(<h> name | msg_staff) \
];

//        dblk_t.
#define dbuf(name ...) \
name[label=QUOTE(<h> name) xlabel="dblk_t"];

//       queue_t.
//         mblk_t, 
//      msg_staff.
#define queue(name, ...) \
name[ xlabel="queue_t" label=QUOTE(<h> name | \
msg_staff)];

حان الوقت الآن لكتابة ملف الرسم البياني الرئيسي. دعنا نسميها my_graph.dot :


//  my_graph.dot

//      .
#include "common.dot"

digraph queue_demo
{
    rankdir=LR;
    node[shape=Mrecord];

    //     ,
    //  ,       .
    dbuf(d1);
    dbuf(d2);
    dbuf(d2_1);
    dbuf(d2_2);
    dbuf(d3);
    dbuf(d4);

    //  ,      ,
    //     .
    msg(m1);
    msg(m2);
    msg(m2_1);
    msg(m2_2);
    msg(m3);
    msg(m4);

    //     .
    //     q1.
    queue(q1);

    //       .
    m1:d->d1;
    m2:d->d2;
    m2_1:d->d2_1;
    m2_2:d->d2_2;
    m3:d->d3;
    m4:d->d4;

    //     .
    m1:n -> m2:h;
    m1:p -> q1:h;
    m2:n -> m3:h;
    m2:c->m2_1:h;
    m2_1:c->m2_2:h;
    m3:n -> m4:h;

    m2:p -> m1:h;
    m3:p -> m2:h;
    m4:p -> m3:h;

    //      .
    q1:n->m1:h;  
    q1:p->m4:h;
    m4:n -> q1:h[color=blue]; //    .
}

نعالج الملف باستخدام معالج مسبق:


cpp my_graph.dot -o my_graph_res.dot

my_graph_res.dot. :


# 1 "<built-in>"
# 1 "<command-line>"
# 1 "my_graph.dot"

# 1 "common.dot" 1
# 3 "my_graph.dot" 2

digraph queue_demo
{
    rankdir=LR;
    node[shape=Mrecord];

    d1[label="<h> d1" xlabel="dblk_t"];;
    d2[label="<h> d2" xlabel="dblk_t"];;
    d2_1[label="<h> d2_1" xlabel="dblk_t"];;
    d2_2[label="<h> d2_2" xlabel="dblk_t"];;
    d3[label="<h> d3" xlabel="dblk_t"];;
    d4[label="<h> d4" xlabel="dblk_t"];;

    m1[xlabel=mblk_t label="<h> m1 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;
    m2[xlabel=mblk_t label="<h> m2 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;
    m2_1[xlabel=mblk_t label="<h> m2_1 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;
    m2_2[xlabel=mblk_t label="<h> m2_2 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;
    m3[xlabel=mblk_t label="<h> m3 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;
    m4[xlabel=mblk_t label="<h> m4 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff" ];;

    q1[ xlabel="queue_t" label="<h> q1 | <p> *prev |<n> *next |<c> *cont |<d> *data | other\nstuff"];;

    m1:d->d1;
    m2:d->d2;
    m2_1:d->d2_1;
    m2_2:d->d2_2;
    m3:d->d3;
    m4:d->d4;

    m1:n -> m2:h;
    m1:p -> q1:h;
    m2:n -> m3:h;
    m2:c->m2_1:h;
    m2_1:c->m2_2:h;
    m3:n -> m4:h;

    m2:p -> m1:h;
    m3:p -> m2:h;
    m4:p -> m3:h;

    q1:n->m1:h;
    q1:p->m4:h;
    m4:n -> q1:h[color=blue];
}

, . . Graphviz ( dot) : https://sketchviz.com/new


:



, , .


.


All Articles