{"id":17373,"date":"2009-07-24T10:00:00","date_gmt":"2009-07-24T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2009\/07\/24\/if-you-wished-a-language-supported-the-preprocessor-you-know-you-can-fix-that\/"},"modified":"2009-07-24T10:00:00","modified_gmt":"2009-07-24T10:00:00","slug":"if-you-wished-a-language-supported-the-preprocessor-you-know-you-can-fix-that","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20090724-00\/?p=17373","title":{"rendered":"If you wished a language supported the preprocessor, you know, you can fix that"},"content":{"rendered":"<p>\nA customer had the following question about the\n<a HREf=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/aa385638(VS.85).aspx\">\nmessage compiler<\/a>,\nsomething that I had noted\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2007\/05\/29\/2955171.aspx\">\nalmost nobody uses<\/a>.\nWell how do you do, we found somebody who actually uses it.\nAnyway, the question went like this (paraphrased, as always):\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nCan I use symbolic constants in my .mc file?\nFor example, I have a message file that goes like this:\n<\/p>\n<pre>\nSymbolicName=ERROR_XYZ_TOO_LARGE\nThe XYZ parameter cannot exceed 100.\n.\nSymbolicName=ERROR_ABC_TOO_SMALL\nThe ABC parameter must be at least 1.\n.\nSymbolicName=ERROR_CANT_COMBINE_ABC_WITH_XYZ\nYou cannot specify values for both ABC and XYZ.\n.\n<\/pre>\n<p>\nI have symbols defined in a header file\n<code>#define MINIMUM_ABC_VALUE 1<\/code> and\n<code>#define MAXIMUM_XYZ_VALUE 100<\/code>\nthat I, of course, have to keep in sync with the error messages.\nOne way to do this is to change the messages:\n<\/p>\n<pre>\nSymbolicName=ERROR_XYZ_TOO_LARGE\nThe XYZ parameter cannot exceed %1!d!.\n.\nSymbolicName=ERROR_ABC_TOO_SMALL\nThe ABC parameter must be at least %1!d!.\n.\n<\/pre>\n<p>\nAnd in my function that prints error messages, I can insert\nthese magic parameters:\n<\/p>\n<pre>\nerror = DoMyThing(...);\nif (error != ERROR_SUCCESS) {\n switch (error) {\n case ERROR_ABC_TOO_SMALL:\n  Insertion = MINIMUM_ABC_VALUE;\n  break;\n case ERROR_XYZ_TOO_LARGE:\n  Insertion = MAXIMUM_XYZ_VALUE;\n  break;\n case ERROR_CANT_COMBINE_ABC_WITH_XYZ:\n  Insertion = 0; \/\/ not used\n  break;\n ... repeat for other error messages...\n }\n DWORD_PTR Parameters[1] = { Insertion };\n FormatMessage(FORMAT_MESSAGE_ARGUMENT_ARRAY ...\n     ..., error, ..., (va_list*)&amp;Parameters)...\n}\n<\/pre>\n<p>\nThis is obviously a rather high-maintenance approach.\nIs there some way I could just write, say,\n<\/p>\n<pre>\nSymbolicName=ERROR_XYZ_TOO_LARGE\nThe XYZ parameter cannot exceed {MAXIMUM_XYZ_VALUE}.\n.\nSymbolicName=ERROR_ABC_TOO_SMALL\nThe ABC parameter must be at least {MINIMUM_ABC_VALUE}.\n.\n<\/pre>\n<p>\nand have the message compiler do the substitution?\nIt would be great if it could even take the values from my header files.\n<\/p>\n<\/blockquote>\n<p>\nThis is a case of standing right next to the answer and not even realizing it.\n<\/p>\n<p>\nThere&#8217;s no law that says that you&#8217;re not allowed to use any other tools.\nIt so happens that the preprocessor is a handy tool.\nIf you want the preprocessor to run over your message files before\nthey go into the message table,\nthen why not run the preprocessor over your message files\nbefore they go into the message table?\n<\/p>\n<pre>\n#include \"qqlimits.h\" \/\/ pretend the program's name is \"qq\"\n...\nSymbolicName=ERROR_XYZ_TOO_LARGE\nThe XYZ parameter cannot exceed MAXIMUM_XYZ_VALUE.\n.\nSymbolicName=ERROR_ABC_TOO_SMALL\nThe ABC parameter must be at least MINIMUM_ABC_VALUE.\n.\nSymbolicName=ERROR_CANT_COMBINE_ABC_WITH_XYZ\nYou cannot specify values for both ABC and XYZ.\n.\n<\/pre>\n<p>\nGive this file a name like, say, <code>qq.mcp<\/code>,\nand add a rule to your makefile:\n<\/p>\n<pre>\nqq.mc: qq.mcp qqlimits.h\n  cl \/EP qq.mcp &gt;qq.mc\n<\/pre>\n<p>\nMake your changes to <code>qq.mcp<\/code>, and when you build,\nthe makefile will preprocess it and generate the <code>qq.mc<\/code>\nfile, which you can then compile with the message compiler just\nlike you were doing before.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer had the following question about the message compiler, something that I had noted almost nobody uses. Well how do you do, we found somebody who actually uses it. Anyway, the question went like this (paraphrased, as always): Can I use symbolic constants in my .mc file? For example, I have a message file [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-17373","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer had the following question about the message compiler, something that I had noted almost nobody uses. Well how do you do, we found somebody who actually uses it. Anyway, the question went like this (paraphrased, as always): Can I use symbolic constants in my .mc file? For example, I have a message file [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/17373","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=17373"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/17373\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=17373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=17373"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=17373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}