Попытка сделать двуязычные макросы между z/OS HLASM и компилятором XL C/C++ metal C

Я пытаюсь понять, как включить определения HLASM и Metal C для одного и того же DSECT/структуры в один набор данных/файл.

Прежде чем попробовать это, я попробовал то, что описал в Как мне заставить это работать с помощью #include? Он отлично работает, если вставить его прямо в код

Итак, я пошел другим путем и решил, что могу использовать #define, чтобы изменить оператор MACRO в ассемблере на что-то, что будет использовать компилятор C:

  • Измените «MACRO» на «#pragma margins (2,72)».
  • Измените «ИСПРАВИТЬ» на «#pragma nomargins»

    EDIT       SSAF.METALC.H(CKKTEST) - 01.01                          Columns 00001 00080 
    Command ===>                                                          Scroll ===> CSR  
    ****** ********************************* Top of Data **********************************
    000001          MACRO                                                                  
    000002 */* First line of macro prolog                                       */         
    000003 */* Last line of macro prolog                                        */         
    000004 *#if 0!=0                               // Bypass asm in C                      
    000005 Test     DSECT                                                                  
    000006 Test@    DS A                                                                   
    000007 TestINT  DS F                                                                   
    000008 TestChar DS C                                                                   
    000009 *#endif                                                                         
    000010  MEND                                                                           
    000011 struct Test {                                                                   
    000012   void *Test@;                                                                  
    000013   int TestInt;                                                                  
    000014   char TestChar;                                                                
    000015 };                                                                              
    ****** ******************************** Bottom of Data ********************************
    

И я подумал, что могу использовать #define, чтобы изменить «MACRO» и «MEND» на то, что нужно компилятору C, сначала я попробовал без кавычек:

    EDIT       SSAF.METALC.C(CKLTHING) - 01.01                         Columns 00001 00080 
    Command ===>                                                          Scroll ===> CSR  
    000207 #define MACRO #pragma margins(2,72)                                          
    000208 #define MEND #pragma nomargins                                              
    000209 #include"ckktest.h"                                                             

Что не дало желаемые результаты:

    |
      207       |#define MACRO #pragma margins(2,72)                                         
      208       |#define MEND #pragma nomargins                                              
      209       |#include"ckktest.h"                                                         
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3166 Definition of function pragma requires parentheses.      
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3276 Syntax error: possible missing '{'?                                            

Затем я попытался заключить значение #define в кавычки:

      207       |#define MACRO "#pragma margins(2,72)"                                       
      208       |#define MEND "#pragma nomargins"                                            
      209       |#include"ckktest.h"                                                         
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
    *=ERROR===========>     CCN3191 The character # is not a valid C source character.       
      210       |                                                                            

Это дает меньше сообщений об ошибках, но все же это не то, что мне нужно.

Примечание: я использую # EBCDIC 7B.

Описание сообщения об ошибке довольно краткое:

CCN3191 Символ &1 не является допустимым исходным символом C. Объяснение Информацию о допустимых символах см. в Справочнике по языку C/C++.

В тексте сообщения:

&1 - символ.

Действия пользователя Измените символ.

Я обратился к Справочнику по языку C/C++ и не смог найти ничего, что говорило бы о том, что я не могу использовать "#" внутри #define. Собственно говоря, есть несколько слов об операторах # и ##...

Есть ли способ обойти это?

Спасибо, Скотт


person Scott Fagen    schedule 07.10.2019    source источник
comment
Это похоже на трехъязычие, а не на двуязычие. C и C++ - это разные языки. Не смешивайте их; это принесет вам обличительные речи и отрицательные голоса на SO. Я отмечаю, что вы отметили вопрос только с помощью C, а не C++; Я предлагаю отредактировать вопрос, чтобы удалить ссылки на С++. Конечно, препроцессор по существу одинаков в C и C++, но тогда язык препроцессора лишь слабо связан с остальными C и C++.   -  person Jonathan Leffler    schedule 07.10.2019
comment
@ Джонатан Леффлер, в z / OS руководства по C и C ++ - одно и то же; название C/C++ Reference. С тем, что пытается сделать Скотт, в данном случае не имеет значения, что есть что, насколько препроцессор. @ Скотт Фаген, включите параметр компилятора SHOWINC. Это расширит #include в списке. Однако у меня могут быть плохие новости. Правильный синтаксис для #pragma#pragma options(blah) Но в doc, MARGINS не указан.   -  person zarchasmpgmr    schedule 07.10.2019
comment
Я не упомянул здесь C++, за исключением того, что продуктом IBM является компилятор XL C/C++. Я кодирую в C. Ray - поля #pragma (2,72), за которыми следует #pragma nomargins, отлично работает, когда только что введен в программу (и компилятор добросовестно игнорирует то, что находится в столбце 1). Проблема заключается в том, чтобы заставить #define принимать строку, начинающуюся с #, как что-то действительное.   -  person Scott Fagen    schedule 08.10.2019
comment
Мне кажется, я понимаю, что здесь происходит. Это объектно-подобный макрос #define: объектоподобное определение макроса заменяет один идентификатор указанными токенами замены. Идентификатор — это имя для одного из следующих элементов языка: функции, объекты, метки, параметры функций, макросы и параметры макросов, определения типов, перечисляемые типы и перечислители, а также имена структур и объединений. # прагма — это директива препроцессора, которая не является идентификатором. Я думаю, что компилятор интерпретирует это как часть программы, а не предварительную обработку, что соответствует документу.   -  person zarchasmpgmr    schedule 08.10.2019
comment
Могу ли я возразить, зачем вообще использовать двуязычные заголовки/макросы? Я понимаю, что заголовок и макрос описывают одну и ту же структуру, но это усложняет и ухудшает читабельность.   -  person meat    schedule 08.10.2019
comment
Макросы IBM z/OS двуязычны: для ассемблера и языка разработки под названием PL/X (который произошел от PL/I). Многие системные макросы являются двуязычными, они используют производные поля PL/I 2,72 для пропуска звездочки в столбце 1 (комментарий) и используют директивы препроцессора, такие как %GOTO, для пропуска текста на ассемблере.   -  person zarchasmpgmr    schedule 08.10.2019
comment
Проверьте SYS1.MACLIB(IAZCMTCB), чтобы узнать, как это делается. Хитрость заключается в создании макросов ассемблера nop для #ifndef и #define :)   -  person David Crayford    schedule 28.01.2020
comment
На самом деле хитрость заключается в создании фиктивных кодов операций - см. SYS1.MACLIB(IAZDUMOP)   -  person David Crayford    schedule 28.01.2020


Ответы (1)


Скотт, проблема в том, что макрос не может расширяться до директив предварительной обработки. Я предполагаю из заголовка, что вы хотите определить определение структуры в одном месте и использовать его в hlasm и C/C++. Я предлагаю взглянуть на инструмент dsect. Этот инструмент создает объявление структуры C из объявлений DSECT в файле hlasm. Это может дать решение.

Другой вариант использования макросов для ckktest.h выглядит примерно так:

StructStart(Test)
MbrAddr(Test@)
MbrInt(TestINT)
MbrByte(TestChar)
StructEnd

В источник C вы должны включить:

#define StructStart(s) struct s {
#define MbrAddr(m) void *m;
#define MbrInt(m) int m;
#define MbrByte(m) char m;
#define StructEnd };
#include "ckktest.h"

И, как правило, похожи в хлазме.

Я бы посмотрел на инструмент dsect, так как он даст сопоставление с hlasm на C и позволит вам поддерживать одно определение. В вашем make-файле будет одно дополнительное правило для создания заголовка C из кода hlasm с помощью инструмента dsect.

person S Perry    schedule 08.10.2019
comment
Просто хотел поддержать идею использования инструмента CCNEDSCT вместо того, что вы пытаетесь сделать. Нетривиально иметь действительно совместимые структуры DSECT и C на ассемблере из-за таких вещей, как выравнивание, заполнение, ORG/UNION и т. д. Создание всего, что вы хотите, на ассемблере и автоматическое преобразование его в структуры C является гораздо менее подверженным ошибкам подходом, и это также имеет преимущество работы с такими вещами, как области данных z/OS, так что вам не нужно делать это вручную. - person Valerie R; 08.10.2019
comment
Я намерен использовать инструмент DSECT. Однако инструмент имеет ряд недостатков, которые делают вывод не готовым к прайм-тайму, в том числе отсутствие сохранения комментария, предшествующего DSECT, и невозможность определить типы для указателей, поэтому почти всегда будет ручное вмешательство, которое закончится копирование структуры обратно в тот же файл, что и ассемблерный DSECT. - person Scott Fagen; 08.10.2019
comment
@Scott звучит как работа для Рекса. :) - person zarchasmpgmr; 08.10.2019