home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / mkcommands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.4 KB  |  296 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* */
  19. /* mkcommands.c - munge the commands file and output either a .c file, .h file, or both.
  20.    Created: Chris Toshok, toshok@netscape.com, 18-Feb-1997 
  21. */
  22.  
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28.  
  29. #define LINEBUFFER_SIZE 1000
  30.  
  31. char *munge_filename = NULL;
  32. char *header_filename = "commands.h";
  33. char *table_filename = "commands.c";
  34. int header_munging = 0;
  35. int table_munging = 0;
  36.  
  37. typedef struct {
  38.     char *command;
  39.     char *string;
  40. } CommandInfo;
  41.  
  42. CommandInfo *commands = NULL;
  43. int num_commands = 0;
  44. int alloced_commands = 0;
  45.  
  46. void
  47. write_file_header(FILE *fp)
  48. {
  49.     fprintf(fp,
  50.             "/* AUTOMATICALLY GENERATED FILE.  Do not edit!  Instead,\n"
  51.             "   modify the %s file, and use mkcommands to regenerate\n"
  52.             "   this file. */\n\n", munge_filename);
  53. }
  54.  
  55. void
  56. add_command(char *command, char *string)
  57. {
  58.     if (num_commands == alloced_commands)
  59.         {
  60.             alloced_commands +=300;
  61.             commands = realloc(commands, sizeof(CommandInfo) * alloced_commands);
  62.         }
  63.  
  64.     commands[num_commands].command = strdup(command);
  65.     commands[num_commands].string = strdup(string);
  66.     
  67.     num_commands++;
  68. }
  69.  
  70. static int
  71. compare_function(const void *c1, const void *c2)
  72. {
  73.     CommandInfo *com1 = (CommandInfo*)c1;
  74.     CommandInfo *com2 = (CommandInfo*)c2;
  75.  
  76.     return strcmp(com1->string, com2->string);
  77. }
  78.  
  79. void
  80. sort_commands(void)
  81. {
  82.     /* sort the commands by their string */
  83.     qsort(commands, num_commands, sizeof(CommandInfo), compare_function);
  84. }
  85.  
  86. void
  87. output_header(FILE *fp)
  88. {
  89.     int table_position;
  90.     int i;
  91.  
  92.     write_file_header(fp);
  93.  
  94.     fprintf (fp, "extern char _XfeCommands[];\n");
  95.     fprintf (fp, "extern int _XfeNumCommands;\n");
  96.     fprintf (fp, "extern int _XfeCommandIndices[];\n");
  97.  
  98.     table_position = 0;
  99.     for (i = 0; i < num_commands; i ++)
  100.         {
  101.             fprintf (fp, "#define %s ((char*)&_XfeCommands[ %d ])\n", commands[i].command, table_position);
  102.             
  103.             table_position += strlen(commands[i].string) + 1;
  104.         }
  105.  
  106.     fclose(fp);
  107. }
  108.  
  109. void
  110. output_table(FILE *fp)
  111. {
  112.     int i;
  113.     int table_position;
  114.  
  115.     write_file_header(fp);
  116.  
  117.     fprintf (fp,
  118.              "int _XfeNumCommands = %d;\n", num_commands);
  119.  
  120.     fprintf (fp,
  121.              "int _XfeCommandIndices[] = {\n");
  122.  
  123.     table_position = 0;
  124.     for (i = 0; i < num_commands; i ++)
  125.         {
  126.             fprintf (fp, "\t%d,", table_position);
  127.             if (i % 4 == 0) fprintf (fp, "\n");
  128.             table_position += strlen(commands[i].string) + 1;
  129.         }
  130.  
  131.     fprintf (fp,
  132.              "};\n");
  133.  
  134.     fprintf (fp, 
  135.              "char _XfeCommands[] = \n");
  136.  
  137.     table_position = 0;
  138.     for (i = 0; i < num_commands; i ++)
  139.         {
  140.             fprintf (fp, "\t/* %10d */ \"%s\\0\"\n", table_position, commands[i].string);
  141.  
  142.             table_position += strlen(commands[i].string) + 1;
  143.         }
  144.  
  145.     /* write out the closing semicolon. */
  146.     fprintf (fp, ";\n");
  147.     fclose(fp);
  148. }
  149.  
  150. void
  151. munge_file(void)
  152. {
  153.     FILE *munge_fp = 0;
  154.     FILE *table_fp = 0;
  155.     FILE *header_fp = 0;
  156.     static char line_buf[LINEBUFFER_SIZE + 1];
  157.  
  158.     if ((munge_fp = fopen(munge_filename, "r")) == NULL)
  159.         {
  160.             fprintf(stderr, "couldn't open '%s' for reading\n", munge_filename);
  161.             exit(-1);
  162.         }
  163.  
  164.     if (header_munging)
  165.         if ((header_fp = fopen(header_filename, "w")) == NULL)
  166.             {
  167.                 fprintf(stderr, "couldn't open '%s' for writing\n", header_filename);
  168.                 exit(-1);
  169.             }
  170.     
  171.     if (table_munging)
  172.         if ((table_fp = fopen(table_filename, "w")) == NULL)
  173.             {
  174.                 fprintf(stderr, "couldn't open '%s' for writing\n", table_filename);
  175.                 exit(-1);
  176.             }
  177.  
  178.     while (fgets(line_buf, LINEBUFFER_SIZE, munge_fp))
  179.         {
  180.             if (line_buf[0] == '#') /* comment lines. */
  181.                 {
  182.                     continue;
  183.                 }
  184.             else /* non comment lines */
  185.                 {
  186.                     char command[100], string[100];
  187.  
  188.                     command[0] = string[0] = 0;
  189.  
  190.                     sscanf(line_buf, " %s %s ", command, string);
  191.  
  192.                     if (!command[0] || !string[0])
  193.                         continue;
  194.  
  195.                     add_command(command, string);
  196.  
  197.                 }
  198.         }
  199.  
  200.     fclose(munge_fp);
  201.  
  202.     sort_commands();
  203.  
  204.     if (header_munging)
  205.         output_header(header_fp);
  206.  
  207.     if (table_munging)
  208.         output_table(table_fp);
  209. }
  210.  
  211. void
  212. usage(void)
  213. {
  214.     fprintf (stderr,
  215.              "Usage:  mkcommands [-header <header_file_name>] [-table <c_file_name>] <command_file>\n"
  216.              "<header_file_name> is the file written out containing the #defines for the strings.\n"
  217.              "<c_file_name> is the file written out containing the compilable string table.\n");
  218. }
  219.  
  220. int
  221. main(int argc, char **argv)
  222. {
  223.     int n = 0;
  224.  
  225.     for (n = 1; n < argc; n ++) 
  226.         {
  227.             if (strcmp(argv[n], "-header") == 0)
  228.                 {
  229.                     if (argc < n+2)
  230.                         {
  231.                             fprintf(stderr, "-header requires an argument\n");
  232.                             usage();
  233.                             return 2;
  234.                         }
  235.  
  236.                     header_filename = strdup(argv[n+1]);
  237.                     header_munging = 1;
  238.                     n++;
  239.                 }
  240.             else if (strcmp(argv[n], "-table") == 0)
  241.                 {
  242.                     if (argc < n+2)
  243.                         {
  244.                             fprintf(stderr, "-table requires an argument\n");
  245.                             usage();
  246.                             return 2;
  247.                         }
  248.  
  249.                     table_filename = strdup(argv[n+1]);
  250.                     table_munging = 1;
  251.                     n++;
  252.                 }
  253.             else
  254.                 {
  255.                     if (munge_filename == NULL)
  256.                         {
  257.                             munge_filename = strdup(argv[n]);
  258.                         }
  259.                     else
  260.                         {
  261.                             fprintf(stderr, "Unknown flag %s\n", argv[n]);
  262.                             usage();
  263.                             return 2;
  264.                         }
  265.                 }
  266.         }
  267.  
  268.     if (!munge_filename)
  269.         {
  270.             fprintf (stderr, "You must specify a command file on the command line.\n");
  271.             usage();
  272.             return 2;
  273.         }
  274.  
  275.     if (!table_munging && !header_munging)
  276.         {
  277.             fprintf (stderr, "Um, like at least one of -table or -header must be specified on the command line\n");
  278.             usage();
  279.             return 2;
  280.         }
  281.  
  282.     /* allocate the initial command table, with 200 elements */
  283.     alloced_commands = 200;
  284.     commands = malloc(sizeof(CommandInfo) * alloced_commands);
  285.     if (!commands)
  286.         {
  287.             fprintf (stderr, "Unable to mallog. You lose\n");
  288.             return 2;
  289.         }
  290.  
  291.     munge_file();
  292.     return 0;
  293. }
  294.  
  295.  
  296.