summaryrefslogtreecommitdiffstats
path: root/private/sdktools/masm/mkmsg.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/masm/mkmsg.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/sdktools/masm/mkmsg.c')
-rw-r--r--private/sdktools/masm/mkmsg.c596
1 files changed, 596 insertions, 0 deletions
diff --git a/private/sdktools/masm/mkmsg.c b/private/sdktools/masm/mkmsg.c
new file mode 100644
index 000000000..21d6359b9
--- /dev/null
+++ b/private/sdktools/masm/mkmsg.c
@@ -0,0 +1,596 @@
+/*
+** MKMSG [-h cfile] [-inc afile] [-asm srcfile [-min|-max]] txtfile
+**
+** take message file and produce assembler source file. lines in txtfile
+** can be of 6 types:
+** 1) "<<NMSG>>" -- use near segment
+** 2) "<<FMSG>>" -- use far segment
+** 3) "#anything" -- comment line (ignore)
+** 4) "" -- blank line (ignore)
+** 5) "handle<tab>number<tab>message_text"
+** -- message with number and symbolic handle
+** 6) "<tab>number<tab>message_text"
+** -- message with number but no symbolic handle
+**
+** the -h file gets "#define handle number" for those messages with handles.
+** the -inc file gets "handle = number" for the same messages. the -asm file
+** gets standard segment definitions, then the messages are placed either in
+** a near segment (MSG) or a far segment (FAR_MSG) depending on if they follow
+** a <<NMSG>> or a <<FMSG>>. if neither is present, <<NMSG>> is assumed. if
+** -min or -max is given with -asm, the minimum or maximum amount of 0-padding
+** is calculated and placed in the .asm file. any combination of the options
+** may be given, and if none are present then the input is only checked for
+** syntactic validity. maximum and minimum amount of padding depends on the
+** length of the individual messages, and is defined in the cp/dos spec
+**
+** If the -32 switch is supplied then the -asm file will be compatible
+** with a 32 bit flat model operating system. In which case <<NMSG>> and
+** <<FMSG>> cause the messages to be placed in two tables. The tables are
+** named MSG_tbl and FAR_MSG_tbl respectively. These are within the 32 bit
+** small model data segment.
+**
+** NOTE: This file is no longer used for NT MASM. Instead its output was
+** converted to asmmsg.h and asmmsg2.h and slimed. This was the quick and
+** dirty way to be able to compile masm for other processors. (Jeff Spencer)
+** For more info read the header on asmmsg2.h.
+**
+** randy nevin, microsoft, 4/86
+** (c)copyright microsoft corp, 1986
+**
+** Modified for 32 bit by Jeff Spencer 10/90
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+
+void SetNear( void );
+void SetFar( void );
+
+char usage[] =
+ "usage: MKMSG [-h cfile] [-inc afile] [-asm srcfile [-min|-max]] [-32] txtfile\n";
+char ex[] = "expected escape sequence: %s\n";
+
+char n1[] = "HDR segment byte public \'MSG\'\nHDR ends\n";
+char n2[] = "MSG segment byte public \'MSG\'\nMSG ends\n";
+char n3[] = "PAD segment byte public \'MSG\'\nPAD ends\n";
+char n4[] = "EPAD segment byte common \'MSG\'\nEPAD ends\n";
+char n5[] = "DGROUP group HDR,MSG,PAD,EPAD\n\n";
+
+char f1[] = "FAR_HDR segment byte public \'FAR_MSG\'\nFAR_HDR ends\n";
+char f2[] = "FAR_MSG segment byte public \'FAR_MSG\'\nFAR_MSG ends\n";
+char f3[] = "FAR_PAD segment byte public \'FAR_MSG\'\nFAR_PAD ends\n";
+char f4[] = "FAR_EPAD segment byte common \'FAR_MSG\'\nFAR_EPAD ends\n";
+char f5[] = "FMGROUP group FAR_HDR,FAR_MSG,FAR_PAD,FAR_EPAD\n\n";
+
+int f32Bit = 0; /* -32?, produce 32bit flat model code */
+char didnear = 0;
+char didfar = 0;
+FILE *fasm = NULL; /* -asm stream */
+
+_CRTAPI1 main( argc, argv )
+ int argc;
+ char **argv;
+ {
+ FILE *f; /* the input file */
+ char *h = NULL; /* -h file name */
+ FILE *fh = NULL; /* -h stream */
+ char *inc = NULL; /* -inc file name */
+ FILE *finc = NULL; /* -inc stream */
+ char *asm = NULL; /* -asm file name */
+ int min = 0; /* -min? */
+ int max = 0; /* -max? */
+ int asmstate = 0; /* 0=nothing, 1=doing nmsg, 2=doing fmsg */
+ int instring; /* db "... */
+ char buf[256]; /* line buffer */
+ int ch;
+ int i;
+ int number; /* index of message number in line */
+ int msg; /* index of message text in line */
+ int npad = 0; /* cumulative amount of near padding */
+ int fpad = 0; /* cumulative amount of far padding */
+ int length;
+ double factor;
+ double result;
+
+ argc--; /* skip argv[0] */
+ argv++;
+
+ while (argc && **argv == '-') /* process options */
+ if (!strcmp( "-h", *argv )) { /* create .h file */
+ argc--;
+ argv++;
+
+ if (!argc)
+ printf( "no -h file given\n" );
+ else if (h) {
+ printf( "extra -h file %s ignored\n", *argv );
+ argc--;
+ argv++;
+ }
+ else { /* remember -h file */
+ h = *argv;
+ argc--;
+ argv++;
+ }
+ }
+ else if (!strcmp( "-inc", *argv )) { /* create .inc file */
+ argc--;
+ argv++;
+
+ if (!argc)
+ printf( "no -inc file given\n" );
+ else if (inc) {
+ printf( "extra -inc file %s ignored\n", *argv );
+ argc--;
+ argv++;
+ }
+ else { /* remember -inc file */
+ inc = *argv;
+ argc--;
+ argv++;
+ }
+ }
+ else if (!strcmp( "-asm", *argv )) { /* create .asm file */
+ argc--;
+ argv++;
+
+ if (!argc)
+ printf( "no -asm file given\n" );
+ else if (asm) {
+ printf( "extra -asm file %s ignored\n", *argv );
+ argc--;
+ argv++;
+ }
+ else { /* remember -asm file */
+ asm = *argv;
+ argc--;
+ argv++;
+ }
+ }
+ else if (!strcmp( "-min", *argv )) { /* minimum padding */
+ argc--;
+ argv++;
+
+ if (min)
+ printf( "redundant -min\n" );
+
+ min = 1;
+ }
+ else if (!strcmp( "-max", *argv )) { /* maximum padding */
+ argc--;
+ argv++;
+
+ if (max)
+ printf( "redundant -max\n" );
+
+ max = 1;
+ }
+ else if (!strcmp( "-32", *argv )) { /* 32bit code */
+ argc--;
+ argv++;
+ f32Bit = 1;
+ }
+ else {
+ printf( "unknown option %s ignored\n", *argv );
+ argc--;
+ argv++;
+ }
+
+ if ((min || max) && !asm) {
+ printf( "-min/-max ignored; no -asm file\n" );
+ min = max = 0;
+ }
+
+ if (min && max) {
+ printf( "-min and -max are mutually exclusive; -min chosen\n" );
+ max = 0;
+ }
+
+ if (!argc) { /* no arguments */
+ printf( usage );
+ exit( -1 );
+ }
+
+ if (argc != 1) /* extra arguments */
+ printf( "ignoring extra arguments\n" );
+
+ if (!(f = fopen( *argv, "rb" ))) {
+ printf( "can't open txtfile %s for binary reading\n", *argv );
+ exit( -1 );
+ }
+
+ if (asm && !(fasm = fopen( asm, "w" ))) {
+ printf( "can't open -asm file %s for writing\n", asm );
+ exit( -1 );
+ }
+
+ if (h && !(fh = fopen( h, "w" ))) {
+ printf( "can't open -h file %s for writing\n", h );
+ exit( -1 );
+ }
+
+ if (inc && !(finc = fopen( inc, "w" ))) {
+ printf( "can't open -inc file %s for writing\n", inc );
+ exit( -1 );
+ }
+
+ if( fasm && f32Bit ){
+ fprintf( fasm, "\t.386\n" );
+ fprintf( fasm, "\t.model small,c\n" );
+ fprintf( fasm, "\t.data\n\n" );
+ }
+
+ while ((ch = getc( f )) != EOF) /* process lines */
+ if (ch == '<') { /* <<NMSG>> or <<FMSG>> */
+ buf[0] = ch;
+ i = 1;
+
+ while ((ch = getc( f )) != EOF && ch != '\r'
+ && ch != '\n')
+ if (i < 255)
+ buf[i++] = ch;
+
+ buf[i] = '\0';
+
+ if (!strcmp( "<<NMSG>>", buf ))/*near msgs follow*/
+ if (asmstate == 0) {
+ if (fasm) {
+ SetNear();
+ asmstate = 1;
+ }
+ }
+ else if (asmstate == 1)
+ printf( "already in nmsg\n" );
+ else if (asmstate == 2) {
+ if (fasm) {
+ if( !f32Bit ){
+ fprintf( fasm, "FAR_MSG ends\n\n" );
+ }
+ SetNear();
+ asmstate = 1;
+ }
+ }
+ else {
+ printf( "internal error\n" );
+ exit( -1 );
+ }
+ else if (!strcmp( "<<FMSG>>", buf ))/*far msgs follow*/
+ if (asmstate == 0) {
+ if (fasm) {
+ SetFar();
+ asmstate = 2;
+ }
+ }
+ else if (asmstate == 1) {
+ if (fasm) {
+ if( !f32Bit ){
+ fprintf( fasm, "MSG ends\n\n" );
+ }
+ SetFar();
+ asmstate = 2;
+ }
+ }
+ else if (asmstate == 2)
+ printf( "already in fmsg\n" );
+ else {
+ printf( "internal error\n" );
+ exit( -1 );
+ }
+ else
+ printf( "ignoring bad line: %s\n", buf );
+ }
+ else if (ch == '#') /* comment line */
+ while ((ch = getc( f )) != EOF && ch != '\r'
+ && ch != '\n')
+ ;
+ else if (ch != '\r' && ch != '\n') { /* something to do */
+ buf[0] = ch;
+ i = 1;
+
+ while ((ch = getc( f )) != EOF && ch != '\r'
+ && ch != '\n')
+ if (i < 255)
+ buf[i++] = ch;
+
+ buf[i] = '\0';
+
+ if (buf[i = 0] != '\t')
+ while (buf[i] && buf[i] != '\t')
+ i++;
+
+ if (!buf[i]) {
+ printf( "expected <TAB>: %s\n", buf );
+ continue;
+ }
+ else
+ i++;
+
+ if (!buf[i] || buf[i] == '\t') {
+ printf( "expected msgnum: %s\n", buf );
+ continue;
+ }
+
+ number = i;
+
+ while (buf[i] && buf[i] != '\t')
+ i++;
+
+ if (buf[i] != '\t') {
+ printf( "expected <TAB>: %s\n", buf );
+ continue;
+ }
+
+ msg = ++i;
+
+ if (buf[0] != '\t') { /* possible -h and/or -inc */
+ if (h) {
+ fprintf( fh, "#define\t" );
+
+ for (i = 0; i < msg-1; i++)
+ putc( buf[i], fh );
+
+ putc( '\n', fh );
+ }
+
+ if (inc) {
+ for (i = 0; i < number; i++)
+ putc( buf[i], finc );
+
+ fprintf( finc, "=\t" );
+
+ while (i < msg-1)
+ putc( buf[i++], finc );
+
+ putc( '\n', finc );
+ }
+ }
+
+ if (fasm) { /* write asmfile */
+ if (asmstate == 0) {
+ SetNear();
+ asmstate = 1;
+ }
+
+ fprintf( fasm, "\tdw\t" );
+
+ for (i = number; i < msg-1; i++)
+ putc( buf[i], fasm );
+
+ fprintf( fasm, "\n\tdb\t" );
+ instring = 0;
+
+ for (i = msg, length = 0; buf[i];
+ i++, length++)
+ /* allocate message */
+ if (buf[i] == '\\')
+ /* C escape sequence */
+ switch (buf[++i]) {
+ case 'r':
+ case 'n':
+ case 't':
+ case 'f':
+ case 'v':
+ case 'b':
+ case '\'':
+ case '"':
+ case '\\':
+ if (instring) {
+ putc( '"',
+ fasm );
+ putc( ',',
+ fasm );
+ instring = 0;
+ }
+
+ if (buf[i] == 'r')
+ fprintf( fasm,
+ "13" );
+ else if (buf[i] == 'n')
+ fprintf( fasm,
+ "10" );
+ else if (buf[i] == 't')
+ fprintf( fasm,
+ "9" );
+ else if (buf[i] == 'f')
+ fprintf( fasm,
+ "12" );
+ else if (buf[i] == 'v')
+ fprintf( fasm,
+ "11" );
+ else if (buf[i] == 'b')
+ fprintf( fasm,
+ "8" );
+ else if (buf[i] == '\'')
+ fprintf( fasm,
+ "39" );
+ else if (buf[i] == '"')
+ fprintf( fasm,
+ "34" );
+ else if (buf[i] == '\\')
+ fprintf( fasm,
+ "92" );
+
+ putc( ',', fasm );
+ break;
+ case '\0':
+ printf( ex, buf );
+ i--;
+ break;
+ default:
+ if (!instring) {
+ putc( '"',
+ fasm );
+ instring = 1;
+ }
+
+ putc( buf[i], fasm );
+ break;
+ }
+ else if (instring)
+ /* keep building string */
+ putc( buf[i], fasm );
+ else { /* start building string */
+ putc( '"', fasm );
+ instring = 1;
+ putc( buf[i], fasm );
+ }
+
+ if (instring) { /* close string */
+ putc( '"', fasm );
+ putc( ',', fasm );
+ }
+
+ putc( '0', fasm );
+ putc( '\n', fasm );
+
+ /* calculate padding */
+ /* depends on msg length */
+
+ if (min || max) {
+ if (min)
+ if (length <= 10)
+ factor = 1.01;
+ else if (length <= 20)
+ factor = 0.81;
+ else if (length <= 30)
+ factor = 0.61;
+ else if (length <= 50)
+ factor = 0.41;
+ else if (length <= 70)
+ factor = 0.31;
+ else
+ factor = 0.30;
+ else if (length <= 10)
+ factor = 2.00;
+ else if (length <= 20)
+ factor = 1.00;
+ else if (length <= 30)
+ factor = 0.80;
+ else if (length <= 50)
+ factor = 0.60;
+ else if (length <= 70)
+ factor = 0.40;
+ else
+ factor = 0.30;
+
+ result = (double)length * factor;
+
+ if (asmstate == 1) {
+ npad += (int)result;
+
+ if (result
+ > (float)((int)result))
+ npad++;
+ }
+ else if (asmstate == 2) {
+ fpad += (int)result;
+
+ if (result
+ > (float)((int)result))
+ fpad++;
+ }
+ }
+ }
+ }
+
+ if (fasm) { /* finish up asm file */
+ if( !f32Bit ){
+ if (asmstate == 1)
+ fprintf( fasm, "MSG ends\n\n");
+ else if (asmstate == 2)
+ fprintf( fasm, "FAR_MSG ends\n\n");
+
+ if (npad) { /* add near padding */
+ fprintf( fasm, "PAD segment\n\tdb\t%d dup(0)\n",
+ npad );
+ fprintf( fasm, "PAD ends\n\n" );
+ }
+
+ if (fpad) { /* add far padding */
+ fprintf( fasm, "FAR_PAD segment\n\tdb\t%d dup(0)\n",
+ fpad );
+ fprintf( fasm, "FAR_PAD ends\n\n" );
+ }
+ }
+ fprintf( fasm, "\tend\n" );
+ fclose( fasm );
+ }
+
+ if (fh)
+ fclose( fh );
+
+ if (finc)
+ fclose( finc );
+
+ fclose( f );
+ exit( 0 );
+ }
+
+
+void SetNear()
+{
+ if( f32Bit ) {
+ if( !didnear ){
+ fprintf( fasm, "MSG_tbl EQU $\n" );
+ fprintf( fasm, "\tpublic MSG_tbl\n" );
+ didnear++;
+ }
+ else{
+ /* Rather than modify mkmsg to handle mixed NEAR / FAR */
+ /* I (Jeff Spencer) chose the quick route of limiting it's capabilities */
+ /* As this capability wasn't needed for MASM 5.1 */
+ printf( "error - 32 bit version doesn't support alternating NEAR and FAR messages\n" );
+ exit( -1 );
+ }
+ }
+ else{
+ if (!didnear) {
+ didnear++;
+ fprintf( fasm, n1 );
+ fprintf( fasm, n2 );
+ fprintf( fasm, n3 );
+ fprintf( fasm, n4 );
+ fprintf( fasm, n5 );
+ }
+
+ fprintf( fasm,
+ "MSG segment\n" );
+ }
+ }
+
+
+
+
+
+void SetFar()
+{
+
+ if( f32Bit ){
+ if( !didfar ){
+ fprintf( fasm, "FAR_MSG_tbl EQU $\n" );
+ fprintf( fasm, "\tpublic FAR_MSG_tbl\n" );
+ didfar++;
+ }
+ else{
+ /* Rather than modify mkmsg to handle mixed NEAR / FAR */
+ /* I (Jeff Spencer) chose the quick route of limiting it's capabilities */
+ /* As this capability wasn't needed for MASM 5.1 */
+ printf( "error - 32 bit version doesn't support alternating NEAR and FAR messages\n" );
+ exit( -1 );
+ }
+ }
+ else{
+ if (!didfar) {
+ didfar++;
+ fprintf( fasm, f1 );
+ fprintf( fasm, f2 );
+ fprintf( fasm, f3 );
+ fprintf( fasm, f4 );
+ fprintf( fasm, f5 );
+ }
+
+ fprintf( fasm,
+ "FAR_MSG segment\n" );
+ }
+ }
+