home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / program / d / indent / !Indent / c / args next >
Encoding:
Text File  |  1991-02-22  |  14.2 KB  |  420 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)args.c      5.8 (Berkeley) 5/15/89";
  23. #endif /* not lint */
  24.  
  25. /*
  26.  * Argument scanning and profile reading code.  Default parameters are set
  27.  * here as well.
  28.  */
  29.  
  30. #include <ctype.h>
  31. #ifdef __STDC__
  32. #include <stdlib.h> /* getenv */
  33. #else
  34. char       *getenv();
  35. #endif
  36. #include "externs.h"
  37. #include "args.h"
  38. #include "version.h"
  39.  
  40. int else_endif_col;
  41.  
  42. extern char *in_name;
  43.  
  44. /* profile types */
  45. enum profile {PRO_BOOL, /* boolean */
  46.             PRO_INT, /* integer */
  47.             PRO_FONT, /* troff font */
  48.             PRO_IGN, /* ignore it */
  49.             PRO_KEY, /* -T switch */
  50.             PRO_SETTINGS, /* bundled set of settings */
  51.             PRO_PRSTRING /* Print string and exit */
  52.               };
  53.  
  54. /* profile specials for booleans */
  55. enum on_or_off {
  56.   ONOFF_NA, /* Not applicable.  Used in table for non-booleans.  */
  57.   OFF, /* This option turns on the boolean variable in question.  */
  58.   ON  /* it turns it off */
  59. };
  60.  
  61. /* Explicit flags for each option.  */
  62. static int exp_T = 0;
  63. static int exp_bacc = 0;
  64. static int exp_badp = 0;
  65. static int exp_bad = 0;
  66. static int exp_bap = 0;
  67. static int exp_bbb = 0;
  68. static int exp_bc = 0;
  69. static int exp_bli = 0;
  70. static int exp_bl = 0;
  71. static int exp_bs = 0;
  72. static int exp_cdb = 0;
  73. static int exp_cd = 0;
  74. static int exp_ce = 0;
  75. static int exp_ci = 0;
  76. static int exp_cli = 0;
  77. static int exp_cp = 0;
  78. static int exp_cs = 0;
  79. static int exp_c = 0;
  80. static int exp_di = 0;
  81. static int exp_dj = 0;
  82. static int exp_d = 0;
  83. static int exp_eei = 0;
  84. static int exp_ei = 0;
  85. static int exp_fbc = 0;
  86. static int exp_fbx = 0;
  87. static int exp_fb = 0;
  88. static int exp_fc1 = 0;
  89. static int exp_fca = 0;
  90. static int exp_fc = 0;
  91. static int exp_fk = 0;
  92. static int exp_fs = 0;
  93. static int exp_gnu = 0;
  94. static int exp_ip = 0;
  95. static int exp_i = 0;
  96. static int exp_lc = 0;
  97. static int exp_lp = 0;
  98. static int exp_l = 0;
  99. static int exp_pcs = 0;
  100. static int exp_psl = 0;
  101. static int exp_pro = 0;
  102. static int exp_ps = 0;
  103. static int exp_kr = 0;
  104. static int exp_sc = 0;
  105. static int exp_sob = 0;
  106. static int exp_ss = 0;
  107. static int exp_st = 0;
  108. static int exp_troff = 0;
  109. static int exp_v = 0;
  110. static int exp_version = 0;
  111.  
  112. /* The following variables are controlled by command line parameters and
  113.    their meaning is explained in indent_globs.h.  */
  114. int leave_comma;
  115. int decl_com_ind;
  116. int case_indent;
  117. int com_ind;
  118. int decl_indent;
  119. int ljust_decl;
  120. int unindent_displace;
  121. int else_if;
  122. int indent_parameters;
  123. int ind_size;
  124. int blanklines_after_procs;
  125. int use_stdinout;
  126.  
  127. /* Name of where options are currently being read from (one of the
  128.    .indent.pro files, or the command line).  */
  129. char *option_source = "?";
  130.  
  131. /*
  132.  * N.B.: because of the way the table here is scanned, options whose names are
  133.  * substrings of other options must occur later; that is, with -lp vs -l, -lp
  134.  * must be first.  Also, while (most) booleans occur more than once, the last
  135.  * default value is the one actually assigned.
  136.  */
  137. struct pro {
  138.     char       *p_name;         /* name, eg -bl, -cli */
  139.     enum profile p_type;
  140.     int         p_default;      /* the default value (if int) */
  141.  
  142.     /* If p_type == PRO_BOOL, ON or OFF to tell how this switch affects
  143.          the variable.
  144.        Not used for other p_type's.  */
  145.     enum on_or_off p_special;
  146.  
  147.     /* if p_type == PRO_SETTINGS, a (char *) pointing to a list of the
  148.        switches to set, separated by NULs, terminated by 2 NULs.
  149.        if p_type == PRO_BOOL, PRO_INT, or PRO_FONT, address of the
  150.        variable that gets set by the option.
  151.        if p_type == PRO_PRSTRING, a (char *) pointing to the string.  */
  152.     int *p_obj;
  153.  
  154.     /* Points to a nonzero value (allocated statically for all options)
  155.        if the option has been specified explicitly.  This is necessary
  156.        because for boolean options, the options to set and reset the
  157.        variable must share the explicit flag.  */
  158.     int* p_explicit;
  159. };
  160.  
  161. struct pro pro[] = {
  162.  
  163.     {"T", PRO_KEY, 0, ONOFF_NA, 0, &exp_T},
  164.     {"bacc", PRO_BOOL, false, ON,
  165.       &blanklines_around_conditional_compilation, &exp_bacc},
  166.     {"badp", PRO_BOOL, false, ON,
  167.        &blanklines_after_declarations_at_proctop, &exp_badp},
  168.     {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations, &exp_bad},
  169.     {"bap", PRO_BOOL, false, ON, &blanklines_after_procs, &exp_bap},
  170.     {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments, &exp_bbb},
  171.     {"bc", PRO_BOOL, true, OFF, &leave_comma, &exp_bc},
  172.     {"bli", PRO_INT, 0, ONOFF_NA, &brace_indent, &exp_bli},
  173.     {"bl", PRO_BOOL, true, OFF, &btype_2, &exp_bl},
  174.     {"br", PRO_BOOL, true, ON, &btype_2, &exp_bl},
  175.     {"bs", PRO_BOOL, false, ON, &Bill_Shannon, &exp_bs},
  176.     {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline, &exp_cdb},
  177.     {"cd", PRO_INT, 0, ONOFF_NA, &decl_com_ind, &exp_cd},
  178.     {"ce", PRO_BOOL, true, ON, &cuddle_else, &exp_ce},
  179.     {"ci", PRO_INT, 0, ONOFF_NA, &continuation_indent, &exp_ci},
  180.     {"cli", PRO_INT, 0, ONOFF_NA, &case_indent, &exp_cli},
  181.     {"cp", PRO_INT, 33, ONOFF_NA, &else_endif_col, &exp_cp},
  182.     {"cs", PRO_BOOL, true, ON, &cast_space, &exp_cs},
  183.     {"c", PRO_INT, 33, ONOFF_NA, &com_ind, &exp_c},
  184.     {"di", PRO_INT, 16, ONOFF_NA, &decl_indent, &exp_di},
  185.     {"dj", PRO_BOOL, false, ON, &ljust_decl, &exp_dj},
  186.     {"d", PRO_INT, 0, ONOFF_NA, &unindent_displace, &exp_d},
  187.     {"eei", PRO_BOOL, false, ON, &extra_expression_indent, &exp_eei},
  188.     {"ei", PRO_BOOL, true, ON, &else_if, &exp_ei},
  189.     {"fbc", PRO_FONT, 0, ONOFF_NA, (int *) &blkcomf, &exp_fbc},
  190.     {"fbx", PRO_FONT, 0, ONOFF_NA, (int *) &boxcomf, &exp_fbx},
  191.     {"fb", PRO_FONT, 0, ONOFF_NA, (int *) &bodyf, &exp_fb},
  192.     {"fc1", PRO_BOOL, true, ON, &format_col1_comments, &exp_fc1},
  193.     {"fca", PRO_BOOL, true, ON, &format_comments, &exp_fca},
  194.     {"fc", PRO_FONT, 0, ONOFF_NA, (int *) &scomf, &exp_fc},
  195.     {"fk", PRO_FONT, 0, ONOFF_NA, (int *) &keywordf, &exp_fk},
  196.     {"fs", PRO_FONT, 0, ONOFF_NA, (int *) &stringf, &exp_fs},
  197.     {"gnu", PRO_SETTINGS, 0, ONOFF_NA,
  198.       (int *)"-nbad\0-bap\0-nbbb\0-nbc\0-bl\0-ncdb\0-cs\0-nce\0-di1\0-ndj\0\
  199. -ei\0-nfc1\0-i2\0-ip5\0-lp\0-pcs\0-nps\0-psl\0-nsc\0-nsob\0-bli2\0-ss\0\
  200. -cp1\0-nfca\0", &exp_gnu},
  201.     {"ip", PRO_INT, 4, ON, &indent_parameters, &exp_ip},
  202.     {"i", PRO_INT, 4, ONOFF_NA, &ind_size, &exp_i},
  203.     {"kr", PRO_SETTINGS, 0, ONOFF_NA,
  204.        (int *)"-nbad\0-bap\0-nbbb\0-nbc\0-br\0-c33\0-cd33\0-ncdb\0-ce\0\
  205. -ci4\0-cli0\0-d0\0-di1\0-nfc1\0-i4\0-ip0\0-l75\0-lp\0-npcs\0-npsl\0-cs\0\
  206. -nsc\0-nsc\0-nsob\0-nfca\0-cp33\0-nss\0", &exp_kr},
  207.     {"lc", PRO_INT, 0, ONOFF_NA, &block_comment_max_col, &exp_lc},
  208.     {"lp", PRO_BOOL, true, ON, &lineup_to_parens, &exp_lp},
  209.     {"l", PRO_INT, 78, ONOFF_NA, &max_col, &exp_l},
  210.     {"nbacc", PRO_BOOL, false, OFF,
  211.        &blanklines_around_conditional_compilation, &exp_bacc},
  212.     {"nbadp", PRO_BOOL, false, OFF,
  213.        &blanklines_after_declarations_at_proctop, &exp_badp},
  214.     {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations, &exp_bad},
  215.     {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs, &exp_bap},
  216.     {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments, &exp_bbb},
  217.     {"nbc", PRO_BOOL, true, ON, &leave_comma, &exp_bc},
  218.     {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon, &exp_bs},
  219.     {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline, &exp_cdb},
  220.     {"nce", PRO_BOOL, true, OFF, &cuddle_else, &exp_ce},
  221.     {"ncs", PRO_BOOL, true, OFF, &cast_space, &exp_cs},
  222.     {"ndj", PRO_BOOL, false, OFF, &ljust_decl, &exp_dj},
  223.     {"neei", PRO_BOOL, false, OFF, &extra_expression_indent, &exp_eei},
  224.     {"nei", PRO_BOOL, true, OFF, &else_if, &exp_ei},
  225.     {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments, &exp_fc1},
  226.     {"nfca", PRO_BOOL, true, OFF, &format_comments, &exp_fca},
  227.     {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens, &exp_lp},
  228.     {"npcs", PRO_BOOL, false, OFF, &proc_calls_space, &exp_pcs},
  229.     {"npro", PRO_IGN, 0, ONOFF_NA, 0, &exp_pro},
  230.     {"npsl", PRO_BOOL, true, OFF, &procnames_start_line, &exp_psl},
  231.     {"nps", PRO_BOOL, false, OFF, &pointer_as_binop, &exp_ps},
  232.     {"nsc", PRO_BOOL, true, OFF, &star_comment_cont, &exp_sc},
  233.     {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines, &exp_sob},
  234.     {"nss", PRO_BOOL, false, OFF, &space_sp_semicolon, &exp_ss},
  235.     {"nv", PRO_BOOL, false, OFF, &verbose, &exp_v},
  236.     {"pcs", PRO_BOOL, false, ON, &proc_calls_space, &exp_pcs},
  237.     {"psl", PRO_BOOL, true, ON, &procnames_start_line, &exp_psl},
  238.     {"ps", PRO_BOOL, false, ON, &pointer_as_binop, &exp_ps},
  239.     {"sc", PRO_BOOL, true, ON, &star_comment_cont, &exp_sc},
  240.     {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines, &exp_sob},
  241.     {"ss", PRO_BOOL, false, ON, &space_sp_semicolon, &exp_ss},
  242.     {"st", PRO_BOOL, false, ON, &use_stdinout, &exp_st},
  243.     {"troff", PRO_BOOL, false, ON, &troff, &exp_troff},
  244.     {"version", PRO_PRSTRING, 0, ONOFF_NA,
  245.        (int *)VERSION_STRING, &exp_version},
  246.     {"v", PRO_BOOL, false, ON, &verbose, &exp_v},
  247.  
  248.     /* Signify end of structure.  */
  249.     {0, PRO_IGN, 0, ONOFF_NA, 0, 0}
  250. };
  251.  
  252. /*
  253.  * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
  254.  * given in these files.
  255.  */
  256. void set_profile(void)
  257. {
  258.     register FILE *f;
  259. #ifdef __arm /* Name of indent.pro is system dependent */
  260.     static char prof[] = "indent:indent_pro"; /* search via indent$path */
  261. #else
  262.     char *fname;
  263.     static char prof[] = ".indent.pro";
  264.     char *homedir;
  265. #endif
  266.  
  267. #ifdef __arm /* read profile */
  268.              /* Archie version gets benefit of path from OS,
  269.                 BUT doesn't read multple profiles for -T typedef names :-(
  270.                 What we *should* add is scanning profile of directory
  271.                 containing the source file, and sourcefile.pro ... */
  272. #else
  273.     homedir = getenv("HOME");
  274.     fname = xmalloc(strlen(homedir) + 10 + sizeof prof);
  275.     sprintf(fname, "%s/%s", homedir, prof);
  276.     if ((f = fopen(option_source = fname, "r")) != NULL) {
  277.         scan_profile(f);
  278.         (void) fclose(f);
  279.     }
  280.     xfree (fname);  /* Moved in here so only freed if used */
  281. #endif
  282.     if ((f = fopen(option_source = prof, "r")) != NULL) {
  283.         scan_profile(f);
  284.         (void) fclose(f);
  285.     }
  286.     option_source = "Command line";
  287. }
  288.  
  289. void scan_profile(register FILE *f)
  290. {
  291.     register int i;
  292.     register char *p;
  293.     char        buf[BUFSIZ];
  294.  
  295.     while (1) {
  296.         for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
  297.         if (p != buf) {
  298.             *p++ = 0;
  299.             if (verbose)
  300.                 printf("profile: %s\n", buf);
  301.             set_option(buf, 1);
  302.         }
  303.         else if (i == EOF)
  304.             return;
  305.     }
  306. }
  307.  
  308. /* S1 should be a string.  S2 should be a string, perhaps followed by
  309.    an argument.  Compare the two, returning true if they are equal,
  310.    and if they are equal set *START_PARAM to point to the argument
  311.    in S2.  */
  312. int eqin(register char *s1, register char *s2, char **start_param)
  313. {
  314.     while (*s1) {
  315.         if (*s1++ != *s2++)
  316.             return (false);
  317.     }
  318.     *start_param = s2;
  319.     return (true);
  320. }
  321.  
  322. /*
  323.  * Set the defaults.
  324.  */
  325. void set_defaults(void)
  326. {
  327.     register struct pro *p;
  328.  
  329.     for (p = pro; p->p_name; p++)
  330.         if (p->p_type == PRO_BOOL || p->p_type == PRO_INT)
  331.             *p->p_obj = p->p_default;
  332. }
  333.  
  334. /* Process an option ARG (e.g. "-l60").  
  335.    EXPLICIT should be nonzero iff the argument is being explicitly
  336.    specified (as opposed to being taken from a PRO_SETTINGS group of
  337.    settings).  */
  338.  
  339. void set_option (char *arg, int explicit)
  340. {
  341.     struct pro *p;
  342.     char       *param_start;
  343.  
  344.     arg++;                      /* ignore leading "-" */
  345.     for (p = pro; p->p_name; p++)
  346.     if (*p->p_name == *arg && eqin(p->p_name, arg, ¶m_start))
  347.         goto found;
  348.     fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1);
  349.     exit(1);
  350. found:
  351.     /* If the parameter has been explicitly specified, we don't */
  352.     /* want a group of bundled settings to override the explicit */
  353.     /* setting.  */
  354.     if (explicit || !*(p->p_explicit))
  355.       {
  356.         if (explicit)
  357.           *(p->p_explicit) = 1;
  358.         
  359.         switch (p->p_type) {
  360.           
  361.         case PRO_PRSTRING:
  362.           puts ((char *)p->p_obj);
  363.           exit (0);
  364.  
  365.         case PRO_SETTINGS:
  366.           {
  367.             char *t;  /* current position */
  368.             
  369.             t = (char *)p->p_obj;
  370.             do
  371.               {
  372.                 set_option(t, 0);
  373.                 /* advance to character following next NUL */
  374.                 while (*t++) ;
  375.               }
  376.             while (*t);
  377.           }
  378.           
  379.         case PRO_IGN:
  380.           break;
  381.           
  382.         case PRO_KEY:
  383.           if (*param_start == 0)
  384.             goto need_param;
  385.           {
  386.             register char *str = (char *) xmalloc(strlen(param_start) + 1);
  387.             strcpy(str, param_start);
  388.             addkey(str, 4);
  389.           }
  390.           break;
  391.           
  392.         case PRO_BOOL:
  393.           if (p->p_special == OFF)
  394.             *p->p_obj = false;
  395.           else
  396.             *p->p_obj = true;
  397.           break;
  398.  
  399.         case PRO_INT:
  400.           if (!isdigit(*param_start)) {
  401.         need_param:
  402.               fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n",
  403.                       option_source, arg - 1);
  404.             exit(1);
  405.           }
  406.           *p->p_obj = atoi(param_start);
  407.           break;
  408.           
  409.         case PRO_FONT:
  410.           parsefont((struct fstate *) p->p_obj, param_start);
  411.           break;
  412.           
  413.         default:
  414.           fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
  415.                   p->p_type);
  416.           exit(1);
  417.         }
  418.       }
  419. }
  420.