unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#9560: 24.0.50; c-mode syntax problems
@ 2011-09-20 15:25 Michael Welsh Duggan
       [not found] ` <handler.9560.B.131653264320111.ack@debbugs.gnu.org>
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-09-20 15:25 UTC (permalink / raw)
  To: 9560

I really wish I could give an exact recipe for this, but this particular
failure is extremely transient.  I can leave an emacs open in an bad
state for postmortem diagnosis, but I cannot predict when or under what
conditions this problem and ones similar to it will happen.

In this particular case, I am editing an immediate struct at top level.
For example:

static const sk_stringmap_entry_t field_map_entries[] = {
    {"class",    RWST_CLASS,     "class name",    NULL},
    {"type",     RWST_TYPE,      "type name",     NULL},
    {"flowtype", RWST_FLOWTYPE,  "flowtype name", NULL},
    {"id-flowtype", RWST_FLOWTYPE_ID, "flowtype integer identifier", NULL},
    {"sensor", RWST_SENSOR, "sensor name", NULL},
    {"id-sensor", RWST_SENSOR_ID, "sensor integer identifier", NULL},
    {"describe-sensor", RWST_SENSOR_DESC, "sensor description", NULL},
    {"default-class", RWST_DEFAULT_CLASS, "default class name", NULL},
    {"default-type", RWST_DEFAULT_TYPE, "default type name", NULL},
    {"mark-defaults", RWST_MARK_DEFAULTS, 
     "'+' for default classes, '*' for types", NULL},
    {"class:list", RWST_CLASS_LIST, "list of class names", NULL},
    {"type:list",     RWST_TYPE_LIST,      "list of type names",     NULL},
    {"flowtype:list", RWST_FLOWTYPE_LIST,  "list of flowtype names", NULL},
    {"id-flowtype:list", RWST_FLOWTYPE_ID_LIST,
     "list of flowtype integer identifier", NULL},
    {"sensor:list", RWST_SENSOR, "list of sensor names", NULL},
    {"id-sensor:list", RWST_SENSOR_ID, 
     "list of sensor integer identifier", NULL},
    {"default-class:list", RWST_DEFAULT_CLASS_LIST, 
     "list of default class name", NULL},
    {"default-type:list", RWST_DEFAULT_TYPE_LIST,
            "list of default type name", NULL},
};

Note the indentation of that next-to-last line.  That's because the
syntax thinks it is ((statement-block-intro 4740) (statement-cont
4740)), indent: 12.  It thinks the line above it is ((defun-open 4740)),
indent: 4.  But if I cursor up a few lines before hitting TAB, I get
((brace-list-entry 4557)), indent: 5, and tabbing down from there fixes
the problem.  This has happened to me three times while adding entries
to this struct.  I will include the entire file as I am editing it in
this bug report, in case someone can recreate it by emptying the struct
and typing the stuff in again.

This sort of problem happens to me relatively frequently when editing C
files, on the order of 1-10 times a day.  Usually saving and reloading
the file fixes the problem.  Sometimes reindenting the section does.  If
there is any in-situ debugging I can do when this happens again, please
let me know.

auto-fill-mode (setq
 c-basic-offset 4
 c-comment-only-line-offset '(0 . 0)
 c-indent-comment-alist '((anchored-comment column . 0) (end-block space . 1)
                          (cpp-end-block space . 2))
 c-indent-comments-syntactically-p nil
 c-block-comment-prefix "* "
 c-comment-prefix-regexp '((pike-mode . "//+!?\\|\\**") (awk-mode . "#+")
                           (other . "//+\\|\\**"))
 c-doc-comment-style '((java-mode . javadoc) (pike-mode . autodoc)
                       (c-mode . gtkdoc))
 c-cleanup-list '(scope-operator)
 c-hanging-braces-alist '((substatement-open before after)
                          (arglist-cont-nonempty))
 c-hanging-colons-alist nil
 c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
 c-backslash-column 48
 c-backslash-max-column 72
 c-special-indent-hook '(c-gnu-impose-minimum)
 c-label-minimum-indentation 1
 c-offsets-alist '((inexpr-class . +)
                   (inexpr-statement . +)
                   (lambda-intro-cont . +)
                   (inlambda . c-lineup-inexpr-block)
                   (template-args-cont c-lineup-template-args +)
                   (incomposition . +)
                   (inmodule . +)
                   (innamespace . +)
                   (inextern-lang . +)
                   (composition-close . 0)
                   (module-close . 0)
                   (namespace-close . 0)
                   (extern-lang-close . 0)
                   (composition-open . 0)
                   (module-open . 0)
                   (namespace-open . 0)
                   (extern-lang-open . 0)
                   (objc-method-call-cont
                    c-lineup-ObjC-method-call-colons
                    c-lineup-ObjC-method-call
                    +
                    )
                   (objc-method-args-cont . c-lineup-ObjC-method-args)
                   (objc-method-intro . [0])
                   (friend . 0)
                   (cpp-define-intro c-lineup-cpp-define +)
                   (cpp-macro-cont . +)
                   (cpp-macro . [0])
                   (inclass . +)
                   (stream-op . c-lineup-streamop)
                   (arglist-cont-nonempty
                    c-lineup-gcc-asm-reg
                    c-lineup-arglist
                    )
                   (arglist-cont c-lineup-gcc-asm-reg 0)
                   (comment-intro
                    c-lineup-knr-region-comment
                    c-lineup-comment
                    )
                   (catch-clause . 0)
                   (else-clause . 0)
                   (do-while-closure . 0)
                   (access-label . -)
                   (case-label . *)
                   (substatement . +)
                   (statement-case-intro . *)
                   (statement . 0)
                   (brace-entry-open . 0)
                   (brace-list-entry . 0)
                   (brace-list-intro . +)
                   (brace-list-close . 0)
                   (block-close . 0)
                   (block-open . 0)
                   (inher-cont . c-lineup-multi-inher)
                   (inher-intro . +)
                   (member-init-cont . c-lineup-multi-inher)
                   (member-init-intro . +)
                   (annotation-var-cont . +)
                   (annotation-top-cont . 0)
                   (topmost-intro . 0)
                   (knr-argdecl . 0)
                   (func-decl-cont . +)
                   (inline-close . 0)
                   (class-close . 0)
                   (class-open . 0)
                   (defun-block-intro . +)
                   (defun-close . 0)
                   (defun-open . 0)
                   (c . c-lineup-C-comments)
                   (string . c-lineup-dont-change)
                   (topmost-intro-cont
                    first
                    c-lineup-topmost-intro-cont
                    c-lineup-gnu-DEFUN-intro-cont
                    )
                   (brace-list-open . +)
                   (inline-open . 0)
                   (arglist-close . c-lineup-arglist)
                   (arglist-intro . +)
                   (statement-cont . c-lineup-math)
                   (statement-case-open . *)
                   (label . *)
                   (substatement-label . 0)
                   (substatement-open . 0)
                   (knr-argdecl-intro . 5)
                   (statement-block-intro . +)
                   )
 c-buffer-is-cc-mode 'c-mode
 c-tab-always-indent t
 c-syntactic-indentation t
 c-syntactic-indentation-in-macros t
 c-ignore-auto-fill '(string cpp code)
 c-auto-align-backslashes t
 c-backspace-function 'backward-delete-char-untabify
 c-delete-function 'delete-char
 c-electric-pound-behavior nil
 c-default-style '((java-mode . "java") (awk-mode . "awk") (other . "gnu"))
 c-enable-xemacs-performance-kludge-p nil
 c-old-style-variable-behavior nil
 defun-prompt-regexp nil
 tab-width 8
 comment-column 32
 parse-sexp-ignore-comments t
 parse-sexp-lookup-properties t
 auto-fill-function nil
 comment-multi-line t
 comment-start-skip "\\(//+\\|/\\*+\\)\\s *"
 fill-prefix nil
 fill-column 70
 paragraph-start "[ 	]*\\(//+\\|\\**\\)[ 	]*$\\|^\f"
 adaptive-fill-mode t
 adaptive-fill-regexp "[ 	]*\\(//+\\|\\**\\)[ 	]*\\([ 	]*\\([-–!|#%;>*·•‣⁃◦]+[ 	]*\\)*\\)"
 )

Package: CC Mode 5.31.8 (C/l)
Buffer Style: gnu
c-emacs-features: (pps-extended-state col-0-paren posix-char-classes gen-string-delim gen-comment-delim syntax-properties 1-bit)

In GNU Emacs 24.0.50.1 (i686-pc-linux-gnu, GTK+ Version 2.10.4)
 of 2011-09-19 on waterbuck.yellow.cert.org
Windowing system distributor `The X.Org Foundation', version 11.0.70101000
configured using `configure  '--prefix=/home/mwd' '--without-toolkit-scroll-bars' '--with-gif=no''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=none
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: C/l

Minor modes in effect:
  flyspell-mode: t
  shell-dirtrack-mode: t
  display-time-mode: t
  diff-auto-refine-mode: t
  tooltip-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  abbrev-mode: t

Recent messages:
Reading active file via nndraft...done
Checking new news...done
Don't touch it!  It's the History Eraser Button, you fool!
syntax: ((brace-list-entry 4646)), indent: 5
syntax: ((statement-block-intro 4740) (statement-cont 4740)), indent: 12
Don't touch it!  It's the History Eraser Button, you fool!
Type C-x 1 to remove help window.  
Type "q" in help window to restore its previous buffer.
Auto-saving...
syntax: ((statement-block-intro 4740) (statement-cont 4740)), indent: 12

Features:
(shadow emacsbug apropos align time-stamp tabify whitespace dabbrev
help-mode view vc-svn cc-mode cc-fonts cc-guess cc-menus cc-cmds
cc-styles cc-align cc-engine cc-vars cc-defs browse-url mule-util
mailalias copyright cus-edit cus-start cus-load sendmail flyspell ispell
sort ansi-color gnus-cite mail-extr qp gnus-async gnus-bcklg gnus-ml
gnus-topic nndraft nnmh utf-7 rot13 disp-table epa-file epa derived epg
network-stream starttls nnimap parse-time tls utf7 netrc gnus-agent
gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art mm-uu
mml2015 epg-config mm-view mml-smime mailcap gnus-cache edmacro kmacro
nnir gnus-sum gnus-demon nntp gnus-group gnus-undo nnmail mail-source
nnoo gnutls gnus-start gnus-spec gnus-int gnus-range gnus-win gnus-load
woman man uniquify warnings tramp tramp-compat auth-source eieio
byte-opt bytecomp byte-compile cconv macroexp assoc shell pcomplete
tramp-loaddefs time smime password-cache dig comint server psvn advice
help-fns advice-preload cl log-edit ring pcvs-util add-log diff-mode
easy-mmode pgg pgg-parse pgg-def message format-spec rfc822 mml mml-sec
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev gmm-utils mailheader gnus gnus-ems nnheader
gnus-util time-date mail-utils mm-util mail-prsvr wid-edit generic-x
dired-x easymenu dired regexp-opt tooltip ediff-hook vc-hooks
lisp-float-type mwheel x-win x-dnd tool-bar dnd fontset image fringe
lisp-mode register page menu-bar rfn-eshadow timer select scroll-bar
mouse jit-lock font-lock syntax facemenu font-core frame cham georgian
utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese case-table epa-hook jka-cmpr-hook help simple abbrev
minibuffer loaddefs button faces cus-face files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote make-network-process dbusbind
dynamic-setting system-font-setting font-render-setting move-toolbar gtk
x-toolkit x multi-tty emacs)

-- 
Michael Welsh Duggan
(mwd@cert.org)





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: Acknowledgement (24.0.50; c-mode syntax problems)
       [not found] ` <handler.9560.B.131653264320111.ack@debbugs.gnu.org>
@ 2011-09-20 15:34   ` Michael Welsh Duggan
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-09-20 15:34 UTC (permalink / raw)
  To: 9560@debbugs.gnu.org

[-- Attachment #1: Type: text/plain, Size: 30 bytes --]

I forgot to include the file:

[-- Attachment #2: rwsiteinfo.c --]
[-- Type: text/plain, Size: 14667 bytes --]

/*
** Copyright (C) 2011 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
**
** Use of the SILK system and related source code is subject to the terms
** of the following licenses:
**
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
**
** NO WARRANTY
**
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
** DELIVERABLES UNDER THIS LICENSE.
**
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
** Mellon University, its trustees, officers, employees, and agents from
** all claims or demands made against them (and any related losses,
** expenses, or attorney's fees) arising out of, or relating to Licensee's
** and/or its sub licensees' negligent use or willful misuse of or
** negligent conduct or willful misconduct regarding the Software,
** facilities, or other rights or assistance granted by Carnegie Mellon
** University under this License, including, but not limited to, any
** claims of product liability, personal injury, death, damage to
** property, or violation of any laws or regulations.
**
** Carnegie Mellon University Software Engineering Institute authored
** documents are sponsored by the U.S. Department of Defense under
** Contract FA8721-05-C-0003. Carnegie Mellon University retains
** copyrights in all material produced under this contract. The U.S.
** Government retains a non-exclusive, royalty-free license to publish or
** reproduce these documents, or allow others to do so, for U.S.
** Government purposes only pursuant to the copyright license under the
** contract clause at 252.227.7013.
**
** @OPENSOURCE_HEADER_END@
*/

/*
**  Prints information about SiLK site configurations
**
**  Michael Duggan
**  September 2011
*/


#include <silk/silk.h>

RCSIDENT("$Id$");

#include <silk/skstream.h>
#include <silk/skstringmap.h>
#include <silk/sksite.h>
#include <silk/utils.h>


/* LOCAL DEFINES AND TYPEDEFS */

/* where to write --help output */
#define USAGE_FH stdout


/* LOCAL VARIABLE DEFINITIONS */
typedef enum {
    RWST_CLASS,
    RWST_TYPE,
    RWST_FLOWTYPE,
    RWST_FLOWTYPE_ID,
    RWST_SENSOR,
    RWST_SENSOR_ID,
    RWST_SENSOR_DESC,
    RWST_DEFAULT_CLASS,
    RWST_DEFAULT_TYPE,
    RWST_MARK_DEFAULTS,
    RWST_CLASS_LIST,
    RWST_TYPE_LIST,
    RWST_FLOWTYPE_LIST,
    RWST_FLOWTYPE_ID_LIST,
    RWST_SENSOR_LIST,
    RWST_SENSOR_ID_LIST,
    RWST_DEFAULT_CLASS_LIST,
    RWST_DEFAULT_TYPE_LIST
} rws_type_t;


static const sk_stringmap_entry_t field_map_entries[] = {
    {"class",    RWST_CLASS,     "class name",    NULL},
    {"type",     RWST_TYPE,      "type name",     NULL},
    {"flowtype", RWST_FLOWTYPE,  "flowtype name", NULL},
    {"id-flowtype", RWST_FLOWTYPE_ID, "flowtype integer identifier", NULL},
    {"sensor", RWST_SENSOR, "sensor name", NULL},
    {"id-sensor", RWST_SENSOR_ID, "sensor integer identifier", NULL},
    {"describe-sensor", RWST_SENSOR_DESC, "sensor description", NULL},
    {"default-class", RWST_DEFAULT_CLASS, "default class name", NULL},
    {"default-type", RWST_DEFAULT_TYPE, "default type name", NULL},
    {"mark-defaults", RWST_MARK_DEFAULTS,
     "'+' for default classes, '*' for types", NULL},
    {"class:list", RWST_CLASS_LIST, "list of class names", NULL},
    {"type:list",     RWST_TYPE_LIST,      "list of type names",     NULL},
    {"flowtype:list", RWST_FLOWTYPE_LIST,  "list of flowtype names", NULL},
    {"id-flowtype:list", RWST_FLOWTYPE_ID_LIST,
     "list of flowtype integer identifier", NULL},
    {"sensor:list", RWST_SENSOR, "list of sensor names", NULL},
    {"id-sensor:list", RWST_SENSOR_ID,
     "list of sensor integer identifier", NULL},
    {"default-class:list", RWST_DEFAULT_CLASS_LIST,
     "list of default class name", NULL},
    {"default-type:list", RWST_DEFAULT_TYPE_LIST,
            "list of default type name", NULL},
};


/* OPTIONS SETUP */

typedef enum {
    OPT_NO_TITLES, OPT_NO_COLUMNS, OPT_COLUMN_SEPARATOR,
    OPT_NO_FINAL_DELIMITER, OPT_DELIMITED,
    OPT_OUTPUT_PATH, OPT_PAGER
} appOptionsEnum;

static struct option appOptions[] = {
    {"no-titles",           NO_ARG,       0, OPT_NO_TITLES},
    {"no-columns",          NO_ARG,       0, OPT_NO_COLUMNS},
    {"column-separator",    REQUIRED_ARG, 0, OPT_COLUMN_SEPARATOR},
    {"no-final-delimiter",  NO_ARG,       0, OPT_NO_FINAL_DELIMITER},
    {"delimited",           OPTIONAL_ARG, 0, OPT_DELIMITED},
    {"output-path",         REQUIRED_ARG, 0, OPT_OUTPUT_PATH},
    {"pager",               REQUIRED_ARG, 0, OPT_PAGER},
    {0,0,0,0}               /* sentinel entry */
    {0,0,0,0}           /* sentinel entry */
};

static const char *appHelp[] = {
    "Do not print column headers. Def. Print titles.",
    "Disable fixed-width columnar output. Def. Columnar",
    "Use specified character between columns. Def. '|'",
    "Suppress column delimiter at end of line. Def. No",
    "Shortcut for --no-columns --no-final-del --column-sep=CHAR",
    "Send output to given file path. Def. stdout",
    "Program to invoke to page output. Def. $SILK_PAGER or $PAGER",
    (char *)NULL
};



/* LOCAL FUNCTION PROTOTYPES */

static void appUsageLong(void);
static void appTeardown(void);
static void appSetup(int argc, char **argv);
static int  appOptionsHandler(clientData cData, int opt_index, char *opt_arg);


/* FUNCTION DEFINITIONS */

/*
 *  appUsageLong();
 *
 *    Print complete usage information to USAGE_FH.  Pass this
 *    function to skOptionsSetUsageCallback(); skOptionsParse() will
 *    call this funciton and then exit the program when the --help
 *    option is given.
 */
static void appUsageLong(void)
{
#define USAGE_MSG                                                       \
    ("<SWITCHES>\n"                                                     \
     "\tOutputs information about a SiLK site configuration.\n")

    FILE *fh = USAGE_FH;
    int i;

    fprintf(fh, "%s %s", skAppName(), USAGE_MSG);
    fprintf(fh, "\nSWITCHES:\n");
    skOptionsDefaultUsage(fh);

    for (i = 0; appOptions[i].name; i++ ) {
        fprintf(fh, "--%s %s. ", appOptions[i].name,
                SK_OPTION_HAS_ARG(appOptions[i]));
        switch (appOptions[i].val) {
          case OPT_FIELDS:
            /* Dynamically build the help */
            usageFields(fh);
            break;
          default:
            /* Simple static help text from the appHelp array */
            fprintf(fh, "%s\n", appHelp[i]);
            break;
        }
    }

    skOptionsCtxOptionsUsage(optctx, fh);
}


/*
 *  appTeardown()
 *
 *    Teardown all modules, close all files, and tidy up all
 *    application state.
 *
 *    This function is idempotent.
 */
static void appTeardown(void)
{
    static int teardownFlag = 0;

    if (teardownFlag) {
        return;
    }
    teardownFlag = 1;

#error "Anything you put in setup should now be torn down"
    /* for example, close sample output file */
    skStreamDestroy(&out_ios);

    skAppUnregister();
}


/*
 *  appSetup(argc, argv);
 *
 *    Perform all the setup for this application include setting up
 *    required modules, parsing options, etc.  This function should be
 *    passed the same arguments that were passed into main().
 *
 *    Returns to the caller if all setup succeeds.  If anything fails,
 *    this function will cause the application to exit with a FAILURE
 *    exit status.
 */
static void appSetup(int argc, char **argv)
{
    SILK_FEATURES_DEFINE_STRUCT(features);
    int rv;

    /* verify same number of options and help strings */
    assert((sizeof(appHelp)/sizeof(char *)) ==
           (sizeof(appOptions)/sizeof(struct option)));

    /* register the application */
    skAppRegister(argv[0]);
    skAppVerifyFeatures(&features, NULL);
    skOptionsSetUsageCallback(&appUsageLong);

    /* initialize globals */
#error "Initialize any global variables here"
    /* for example: set global output to NULL */
    out_ios = NULL;

    /* register the options */
    if (skOptionsRegister(appOptions, &appOptionsHandler, NULL)
        || sksiteOptionsRegister(SK_SITE_FLAG_CONFIG_FILE))
    {
        skAppPrintErr("Unable to register options");
        exit(EXIT_FAILURE);
    }

#error "Do any other module setup here"

    /* parse the options */
    arg_index = skOptionsParse(argc, argv);
    if (arg_index < 0) {
        /* options parsing should print error */
        skAppUsage();           /* never returns */
    }

    /* try to load site config file; if it fails, we will not be able
     * to resolve flowtype and sensor from input file names */
    sksiteConfigure(0);

#error "Do any options validation here"

#error "If you expect filenames on command line keep this:"
    /* arg_index is looking at first file name to process */
    if (arg_index == argc) {
        if (FILEIsATty(stdin)) {
            skAppPrintErr("No input files on command line and"
                          " stdin is connected to a terminal");
            skAppUsage();       /* never returns */
        }
    }

#error "If you do NOT expect filenames on command line, keep this:"
    /* check for extraneous arguments */
    if (arg_index != argc) {
        skAppPrintErr("Too many arguments or unrecognized switch '%s'",
                      argv[arg_index]);
        skAppUsage();           /* never returns */
    }

#error "Once all options are set, open input and output"
    /* for example, open a SiLK flow file as an output file */
    rv = skStreamOpenSilkFlow(&out_ios, output_path, SK_IO_WRITE);
    if (rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
        skAppPrintErr("Unable to open output file. Exiting");
        skStreamDestroy(&out_ios);
        exit(EXIT_FAILURE);
    }

    if (atexit(appTeardown) < 0) {
        skAppPrintErr("Unable to register appTeardown() with atexit()");
        appTeardown();
        exit(EXIT_FAILURE);
    }

    return;  /* OK */
}


/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int appOptionsHandler(
    clientData  UNUSED(cData),
    int         opt_index,
    char       *opt_arg)
{
    int rv;

    switch ((appOptionsEnum)opt_index) {
#error "Add options handling here.  Return 1 on failure."

      case OPT_FIRST:           /* remove when real options added */
        /* do something with the argument to the switch; for example,
         * parse as an integer */
        rv = skStringParseUint32(&value, opt_arg, 0, 0);
        if (rv) {
            skAppPrintErr("Invalid %s '%s': %s",
                          appOptions[opt_index].name, opt_arg,
                          skStringParseStrerror(rv));
            return 1;
        }
        break;

      case OPT_SECOND:          /* remove when real options added */
        /* set a flag based on this option */
        flag = 1;
        break;
    }

    return 0;  /* OK */
}


/*
 *  rwios = appNextInput(argc, argv);
 *
 *    Open and return the next input file from the command line or the
 *    standard input if no files were given on the command line.
 */
static skstream_t *appNextInput(int argc, char **argv)
{
    static int initialized = 0;
    skstream_t *rwios = NULL;
    const char *fname = NULL;
    int rv;

    if (arg_index < argc) {
        /* get current file and prepare to get next */
        fname = argv[arg_index];
        ++arg_index;
    } else {
        if (initialized) {
            /* no more input */
            return NULL;
        }
        /* input is from stdin */
        fname = "stdin";
    }

    initialized = 1;

    /* create rwios and open file */
    rv = skStreamOpenSilkFlow(&rwios, fname, SK_IO_READ);
    if (rv) {
        skStreamPrintLastErr(rwios, rv, NULL);
        skStreamDestroy(&rwios);
    }

    return rwios;
}


int main(int argc, char **argv)
{
    skstream_t *in_ios;
    int in_rv = SKSTREAM_OK;
    int rv = SKSTREAM_OK;

    appSetup(argc, argv);                       /* never returns on error */

#error "Loop over files on command line or read from stdin."
#error "Process each file, preferably in a separate function."
    /* For each input, process each record */
    while (NULL != (in_ios = appNextInput(argc, argv))) {
        while ((in_rv = skStreamReadRecord(in_ios, &rwrec)) == SKSTREAM_OK) {
            /* process record */
            rv = skStreamWriteRecord(out_ios, &rwrec);
            if (SKSTREAM_OK != rv) {
                skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
                skStreamDestroy(&in_ios);
                goto END;
            }
        }
        if (SKSTREAM_ERR_EOF != in_rv) {
            skStreamPrintLastErr(in_ios, in_rv, &skAppPrintErr);
        }
        skStreamDestroy(&in_ios);
    }

    rv = skStreamClose(out_ios);
    if (SKSTREAM_OK != rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
    }

  END:
    return ((SKSTREAM_OK == rv) ? EXIT_SUCCESS : EXIT_FAILURE);
}


/*
** Local Variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/

[-- Attachment #3: Type: text/plain, Size: 41 bytes --]


-- 
Michael Welsh Duggan
(mwd@cert.org)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: A dribble file of an emacs -Q session that triggers the problem
  2011-09-20 15:25 bug#9560: 24.0.50; c-mode syntax problems Michael Welsh Duggan
       [not found] ` <handler.9560.B.131653264320111.ack@debbugs.gnu.org>
@ 2011-10-02 18:24 ` Michael Welsh Duggan
  2011-10-10  4:15 ` bug#9560: Cache information during failure Michael Welsh Duggan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-10-02 18:24 UTC (permalink / raw)
  To: 9560

[-- Attachment #1: Type: text/plain, Size: 222 bytes --]

I've managed to trigger this bug in a hopefully repeatable way.  I say
hopefully because I don't know right now how to replay a dribble file.
At any rate, here is what I have:

From emacs -Q, I loaded the following file:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rwsiteinfo-backup.c --]
[-- Type: text/x-csrc, Size: 14006 bytes --]

/*
** Copyright (C) 2011 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
**
** Use of the SILK system and related source code is subject to the terms
** of the following licenses:
**
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
**
** NO WARRANTY
**
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
** DELIVERABLES UNDER THIS LICENSE.
**
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
** Mellon University, its trustees, officers, employees, and agents from
** all claims or demands made against them (and any related losses,
** expenses, or attorney's fees) arising out of, or relating to Licensee's
** and/or its sub licensees' negligent use or willful misuse of or
** negligent conduct or willful misconduct regarding the Software,
** facilities, or other rights or assistance granted by Carnegie Mellon
** University under this License, including, but not limited to, any
** claims of product liability, personal injury, death, damage to
** property, or violation of any laws or regulations.
**
** Carnegie Mellon University Software Engineering Institute authored
** documents are sponsored by the U.S. Department of Defense under
** Contract FA8721-05-C-0003. Carnegie Mellon University retains
** copyrights in all material produced under this contract. The U.S.
** Government retains a non-exclusive, royalty-free license to publish or
** reproduce these documents, or allow others to do so, for U.S.
** Government purposes only pursuant to the copyright license under the
** contract clause at 252.227.7013.
**
** @OPENSOURCE_HEADER_END@
*/

/*
**  Prints information about SiLK site configurations
**
**  Michael Duggan
**  September 2011
*/


#include <silk/silk.h>

RCSIDENT("$Id$");

#include <silk/skstream.h>
#include <silk/skstringmap.h>
#include <silk/sksite.h>
#include <silk/utils.h>


/* LOCAL DEFINES AND TYPEDEFS */

/* where to write --help output */
#define USAGE_FH stdout


/* LOCAL VARIABLE DEFINITIONS */
typedef enum {
    RWST_CLASS,
    RWST_TYPE,
    RWST_FLOWTYPE,
    RWST_FLOWTYPE_ID,
    RWST_SENSOR,
    RWST_SENSOR_ID,
    RWST_SENSOR_DESC,
    RWST_DEFAULT_CLASS,
    RWST_DEFAULT_TYPE,
    RWST_MARK_DEFAULTS,
    RWST_CLASS_LIST,
    RWST_TYPE_LIST,
    RWST_FLOWTYPE_LIST,
    RWST_FLOWTYPE_ID_LIST,
    RWST_SENSOR_LIST,
    RWST_SENSOR_ID_LIST,
    RWST_DEFAULT_CLASS_LIST,
    RWST_DEFAULT_TYPE_LIST
} rws_type_t;


static const sk_stringmap_entry_t field_map_entries[] = {
    {"class",    RWST_CLASS,     "class name",    NULL},
    {"type",     RWST_TYPE,      "type name",     NULL},
    {"flowtype", RWST_FLOWTYPE,  "flowtype name", NULL},
    {"id-flowtype", RWST_FLOWTYPE_ID, "flowtype integer identifier", NULL},
    {"sensor", RWST_SENSOR, "sensor name", NULL},
    {"id-sensor", RWST_SENSOR_ID, "sensor integer identifier", NULL},
    {"describe-sensor", RWST_SENSOR_DESC, "sensor description", NULL},
    {"default-class", RWST_DEFAULT_CLASS, "default class name", NULL},
    {"default-type", RWST_DEFAULT_TYPE, "default type name", NULL},
    {"mark-defaults", RWST_MARK_DEFAULTS,
     "'+' for default classes, '*' for types", NULL},
};


/* OPTIONS SETUP */

typedef enum {
    OPT_NO_TITLES, OPT_NO_COLUMNS, OPT_COLUMN_SEPARATOR,
    OPT_NO_FINAL_DELIMITER, OPT_DELIMITED,
    OPT_OUTPUT_PATH, OPT_PAGER
} appOptionsEnum;

static struct option appOptions[] = {
    {"no-titles",           NO_ARG,       0, OPT_NO_TITLES},
    {"no-columns",          NO_ARG,       0, OPT_NO_COLUMNS},
    {"column-separator",    REQUIRED_ARG, 0, OPT_COLUMN_SEPARATOR},
    {"no-final-delimiter",  NO_ARG,       0, OPT_NO_FINAL_DELIMITER},
    {"delimited",           OPTIONAL_ARG, 0, OPT_DELIMITED},
    {"output-path",         REQUIRED_ARG, 0, OPT_OUTPUT_PATH},
    {"pager",               REQUIRED_ARG, 0, OPT_PAGER},
    {0,0,0,0}               /* sentinel entry */
    {0,0,0,0}           /* sentinel entry */
};

static const char *appHelp[] = {
    "Do not print column headers. Def. Print titles.",
    "Disable fixed-width columnar output. Def. Columnar",
    "Use specified character between columns. Def. '|'",
    "Suppress column delimiter at end of line. Def. No",
    "Shortcut for --no-columns --no-final-del --column-sep=CHAR",
    "Send output to given file path. Def. stdout",
    "Program to invoke to page output. Def. $SILK_PAGER or $PAGER",
    (char *)NULL
};



/* LOCAL FUNCTION PROTOTYPES */

static void appUsageLong(void);
static void appTeardown(void);
static void appSetup(int argc, char **argv);
static int  appOptionsHandler(clientData cData, int opt_index, char *opt_arg);


/* FUNCTION DEFINITIONS */

/*
 *  appUsageLong();
 *
 *    Print complete usage information to USAGE_FH.  Pass this
 *    function to skOptionsSetUsageCallback(); skOptionsParse() will
 *    call this funciton and then exit the program when the --help
 *    option is given.
 */
static void appUsageLong(void)
{
#define USAGE_MSG                                                       \
    ("<SWITCHES>\n"                                                     \
     "\tOutputs information about a SiLK site configuration.\n")

    FILE *fh = USAGE_FH;
    int i;

    fprintf(fh, "%s %s", skAppName(), USAGE_MSG);
    fprintf(fh, "\nSWITCHES:\n");
    skOptionsDefaultUsage(fh);

    for (i = 0; appOptions[i].name; i++ ) {
        fprintf(fh, "--%s %s. ", appOptions[i].name,
                SK_OPTION_HAS_ARG(appOptions[i]));
        switch (appOptions[i].val) {
          case OPT_FIELDS:
            /* Dynamically build the help */
            usageFields(fh);
            break;
          default:
            /* Simple static help text from the appHelp array */
            fprintf(fh, "%s\n", appHelp[i]);
            break;
        }
    }

    skOptionsCtxOptionsUsage(optctx, fh);
}


/*
 *  appTeardown()
 *
 *    Teardown all modules, close all files, and tidy up all
 *    application state.
 *
 *    This function is idempotent.
 */
static void appTeardown(void)
{
    static int teardownFlag = 0;

    if (teardownFlag) {
        return;
    }
    teardownFlag = 1;

#error "Anything you put in setup should now be torn down"
    /* for example, close sample output file */
    skStreamDestroy(&out_ios);

    skAppUnregister();
}


/*
 *  appSetup(argc, argv);
 *
 *    Perform all the setup for this application include setting up
 *    required modules, parsing options, etc.  This function should be
 *    passed the same arguments that were passed into main().
 *
 *    Returns to the caller if all setup succeeds.  If anything fails,
 *    this function will cause the application to exit with a FAILURE
 *    exit status.
 */
static void appSetup(int argc, char **argv)
{
    SILK_FEATURES_DEFINE_STRUCT(features);
    int rv;

    /* verify same number of options and help strings */
    assert((sizeof(appHelp)/sizeof(char *)) ==
           (sizeof(appOptions)/sizeof(struct option)));

    /* register the application */
    skAppRegister(argv[0]);
    skAppVerifyFeatures(&features, NULL);
    skOptionsSetUsageCallback(&appUsageLong);

    /* initialize globals */
#error "Initialize any global variables here"
    /* for example: set global output to NULL */
    out_ios = NULL;

    /* register the options */
    if (skOptionsRegister(appOptions, &appOptionsHandler, NULL)
        || sksiteOptionsRegister(SK_SITE_FLAG_CONFIG_FILE))
    {
        skAppPrintErr("Unable to register options");
        exit(EXIT_FAILURE);
    }

#error "Do any other module setup here"

    /* parse the options */
    arg_index = skOptionsParse(argc, argv);
    if (arg_index < 0) {
        /* options parsing should print error */
        skAppUsage();           /* never returns */
    }

    /* try to load site config file; if it fails, we will not be able
     * to resolve flowtype and sensor from input file names */
    sksiteConfigure(0);

#error "Do any options validation here"

#error "If you expect filenames on command line keep this:"
    /* arg_index is looking at first file name to process */
    if (arg_index == argc) {
        if (FILEIsATty(stdin)) {
            skAppPrintErr("No input files on command line and"
                          " stdin is connected to a terminal");
            skAppUsage();       /* never returns */
        }
    }

#error "If you do NOT expect filenames on command line, keep this:"
    /* check for extraneous arguments */
    if (arg_index != argc) {
        skAppPrintErr("Too many arguments or unrecognized switch '%s'",
                      argv[arg_index]);
        skAppUsage();           /* never returns */
    }

#error "Once all options are set, open input and output"
    /* for example, open a SiLK flow file as an output file */
    rv = skStreamOpenSilkFlow(&out_ios, output_path, SK_IO_WRITE);
    if (rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
        skAppPrintErr("Unable to open output file. Exiting");
        skStreamDestroy(&out_ios);
        exit(EXIT_FAILURE);
    }

    if (atexit(appTeardown) < 0) {
        skAppPrintErr("Unable to register appTeardown() with atexit()");
        appTeardown();
        exit(EXIT_FAILURE);
    }

    return;  /* OK */
}


/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int appOptionsHandler(
    clientData  UNUSED(cData),
    int         opt_index,
    char       *opt_arg)
{
    int rv;

    switch ((appOptionsEnum)opt_index) {
#error "Add options handling here.  Return 1 on failure."

      case OPT_FIRST:           /* remove when real options added */
        /* do something with the argument to the switch; for example,
         * parse as an integer */
        rv = skStringParseUint32(&value, opt_arg, 0, 0);
        if (rv) {
            skAppPrintErr("Invalid %s '%s': %s",
                          appOptions[opt_index].name, opt_arg,
                          skStringParseStrerror(rv));
            return 1;
        }
        break;

      case OPT_SECOND:          /* remove when real options added */
        /* set a flag based on this option */
        flag = 1;
        break;
    }

    return 0;  /* OK */
}


/*
 *  rwios = appNextInput(argc, argv);
 *
 *    Open and return the next input file from the command line or the
 *    standard input if no files were given on the command line.
 */
static skstream_t *appNextInput(int argc, char **argv)
{
    static int initialized = 0;
    skstream_t *rwios = NULL;
    const char *fname = NULL;
    int rv;

    if (arg_index < argc) {
        /* get current file and prepare to get next */
        fname = argv[arg_index];
        ++arg_index;
    } else {
        if (initialized) {
            /* no more input */
            return NULL;
        }
        /* input is from stdin */
        fname = "stdin";
    }

    initialized = 1;

    /* create rwios and open file */
    rv = skStreamOpenSilkFlow(&rwios, fname, SK_IO_READ);
    if (rv) {
        skStreamPrintLastErr(rwios, rv, NULL);
        skStreamDestroy(&rwios);
    }

    return rwios;
}


int main(int argc, char **argv)
{
    skstream_t *in_ios;
    int in_rv = SKSTREAM_OK;
    int rv = SKSTREAM_OK;

    appSetup(argc, argv);                       /* never returns on error */

#error "Loop over files on command line or read from stdin."
#error "Process each file, preferably in a separate function."
    /* For each input, process each record */
    while (NULL != (in_ios = appNextInput(argc, argv))) {
        while ((in_rv = skStreamReadRecord(in_ios, &rwrec)) == SKSTREAM_OK) {
            /* process record */
            rv = skStreamWriteRecord(out_ios, &rwrec);
            if (SKSTREAM_OK != rv) {
                skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
                skStreamDestroy(&in_ios);
                goto END;
            }
        }
        if (SKSTREAM_ERR_EOF != in_rv) {
            skStreamPrintLastErr(in_ios, in_rv, &skAppPrintErr);
        }
        skStreamDestroy(&in_ios);
    }

    rv = skStreamClose(out_ios);
    if (SKSTREAM_OK != rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
    }

  END:
    return ((SKSTREAM_OK == rv) ? EXIT_SUCCESS : EXIT_FAILURE);
}


/*
** Local Variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/

[-- Attachment #3: Type: text/plain, Size: 581 bytes --]


After loading the file, I started a dribble file as follows:

  M-x open-dribble-file RET /tmp/c-mode-debug.dribble RET

I then started editing the file until I encountered the syntax problem.
Near the end of the dribble file, after I encounter the problem, I end
up messing around a bit with turning on the echoing of syntactic
information, and it takes a while for me to get it right.  Please be
warned, that my exiting emacs afterward is contained within the dribble
file, so you may want to remove those characters before replaying it.

Here is the dribble file in question:


[-- Attachment #4: c-mode-debug.dribble --]
[-- Type: application/octet-stream, Size: 2841 bytes --]

[-- Attachment #5: Type: text/plain, Size: 172 bytes --]


I am hoping that my typing sequence is enough to replicate the problem,
and that timing doesn't play any part.  Hope this helps.

-- 
Michael Welsh Duggan
(md5i@md5i.com)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: Cache information during failure
  2011-09-20 15:25 bug#9560: 24.0.50; c-mode syntax problems Michael Welsh Duggan
       [not found] ` <handler.9560.B.131653264320111.ack@debbugs.gnu.org>
  2011-10-02 18:24 ` bug#9560: A dribble file of an emacs -Q session that triggers the problem Michael Welsh Duggan
@ 2011-10-10  4:15 ` Michael Welsh Duggan
  2011-10-13  2:33 ` bug#9560: An exact recipe Michael Welsh Duggan
  2011-10-22 11:26 ` bug#9560: Bug #9560 fixed Alan Mackenzie
  4 siblings, 0 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-10-10  4:15 UTC (permalink / raw)
  To: 9560

[-- Attachment #1: Type: text/plain, Size: 626 bytes --]

I tried recreating the problem again, successfully.  This time, I
evaluated the c-state-dump function in the comments in cc-engine.  Here
is that state data, and the file at that point:

"(setq c-state-cache '(4054 (3986 . 4048)))    (setq c-state-cache-good-pos 4055)    (setq c-state-nonlit-pos-cache 'nil)    (setq c-state-nonlit-pos-cache-limit 3497)    (setq c-state-brace-pair-desert '(3495 . 3986))    (setq c-state-point-min 1)    (setq c-state-point-min-lit-type nil)    (setq c-state-point-min-lit-start nil)    (setq c-state-min-scan-pos 1)    (setq c-state-old-cpp-beg nil)    (setq c-state-old-cpp-end nil)    "


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rwsiteinfo-backup.c --]
[-- Type: text/x-csrc, Size: 13943 bytes --]

/*
** Copyright (C) 2011 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
**
** Use of the SILK system and related source code is subject to the terms
** of the following licenses:
**
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
**
** NO WARRANTY
**
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
** DELIVERABLES UNDER THIS LICENSE.
**
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
** Mellon University, its trustees, officers, employees, and agents from
** all claims or demands made against them (and any related losses,
** expenses, or attorney's fees) arising out of, or relating to Licensee's
** and/or its sub licensees' negligent use or willful misuse of or
** negligent conduct or willful misconduct regarding the Software,
** facilities, or other rights or assistance granted by Carnegie Mellon
** University under this License, including, but not limited to, any
** claims of product liability, personal injury, death, damage to
** property, or violation of any laws or regulations.
**
** Carnegie Mellon University Software Engineering Institute authored
** documents are sponsored by the U.S. Department of Defense under
** Contract FA8721-05-C-0003. Carnegie Mellon University retains
** copyrights in all material produced under this contract. The U.S.
** Government retains a non-exclusive, royalty-free license to publish or
** reproduce these documents, or allow others to do so, for U.S.
** Government purposes only pursuant to the copyright license under the
** contract clause at 252.227.7013.
**
** @OPENSOURCE_HEADER_END@
*/

/*
**  Prints information about SiLK site configurations
**
**  Michael Duggan
**  September 2011
*/


#include <silk/silk.h>

RCSIDENT("$Id$");

#include <silk/skstream.h>
#include <silk/skstringmap.h>
#include <silk/sksite.h>
#include <silk/utils.h>


/* LOCAL DEFINES AND TYPEDEFS */

/* where to write --help output */
#define USAGE_FH stdout


/* LOCAL VARIABLE DEFINITIONS */
typedef enum {
    RWST_CLASS,
    RWST_TYPE,
    RWST_FLOWTYPE,
    RWST_FLOWTYPE_ID,
    RWST_SENSOR,
    RWST_SENSOR_ID,
    RWST_SENSOR_DESC,
    RWST_DEFAULT_CLASS,
    RWST_DEFAULT_TYPE,
    RWST_MARK_DEFAULTS,
    RWST_CLASS_LIST,
    RWST_TYPE_LIST,
    RWST_FLOWTYPE_LIST,
    RWST_FLOWTYPE_ID_LIST,
    RWST_SENSOR_LIST,
    RWST_SENSOR_ID_LIST,
    RWST_DEFAULT_CLASS_LIST,
    RWST_DEFAULT_TYPE_LIST
} rws_type_t;


static const sk_stringmap_entry_t field_map_entries[] = {
    {"class", RWST_CLASS, "class name", NULL},
    {"type", RWST_TYPE, "type name", NULL},
    {"flowtype", RWST_FLOWTYPE, "flowtype name", NULL},
    {"id-flowtype", RWST_FLOWTYPE_ID, "flowtype integer identifier", NULL},
    {"sensor", RWST_SENSOR, "sensor name", NULL},
    {"id-sensor", RWST_SENSOR_ID, "sensor integer identifier", NULL},
    {"describe-sensor", RWST_SENSOR_DESC, "sensor description", NULL},
    {"default-class", RWST_DEFAULT_CLASS, "default class name", NULL},
    {"default-type", RWST_DEFAULT_TYPE, "default type name", NULL},
    {"mark-defaults", RWST_MARK_DEFAULTS, 
            "
};


/* OPTIONS SETUP */

typedef enum {
    OPT_NO_TITLES, OPT_NO_COLUMNS, OPT_COLUMN_SEPARATOR,
    OPT_NO_FINAL_DELIMITER, OPT_DELIMITED,
    OPT_OUTPUT_PATH, OPT_PAGER
} appOptionsEnum;

static struct option appOptions[] = {
    {"no-titles",           NO_ARG,       0, OPT_NO_TITLES},
    {"no-columns",          NO_ARG,       0, OPT_NO_COLUMNS},
    {"column-separator",    REQUIRED_ARG, 0, OPT_COLUMN_SEPARATOR},
    {"no-final-delimiter",  NO_ARG,       0, OPT_NO_FINAL_DELIMITER},
    {"delimited",           OPTIONAL_ARG, 0, OPT_DELIMITED},
    {"output-path",         REQUIRED_ARG, 0, OPT_OUTPUT_PATH},
    {"pager",               REQUIRED_ARG, 0, OPT_PAGER},
    {0,0,0,0}               /* sentinel entry */
    {0,0,0,0}           /* sentinel entry */
};

static const char *appHelp[] = {
    "Do not print column headers. Def. Print titles.",
    "Disable fixed-width columnar output. Def. Columnar",
    "Use specified character between columns. Def. '|'",
    "Suppress column delimiter at end of line. Def. No",
    "Shortcut for --no-columns --no-final-del --column-sep=CHAR",
    "Send output to given file path. Def. stdout",
    "Program to invoke to page output. Def. $SILK_PAGER or $PAGER",
    (char *)NULL
};



/* LOCAL FUNCTION PROTOTYPES */

static void appUsageLong(void);
static void appTeardown(void);
static void appSetup(int argc, char **argv);
static int  appOptionsHandler(clientData cData, int opt_index, char *opt_arg);


/* FUNCTION DEFINITIONS */

/*
 *  appUsageLong();
 *
 *    Print complete usage information to USAGE_FH.  Pass this
 *    function to skOptionsSetUsageCallback(); skOptionsParse() will
 *    call this funciton and then exit the program when the --help
 *    option is given.
 */
static void appUsageLong(void)
{
#define USAGE_MSG                                                       \
    ("<SWITCHES>\n"                                                     \
     "\tOutputs information about a SiLK site configuration.\n")

    FILE *fh = USAGE_FH;
    int i;

    fprintf(fh, "%s %s", skAppName(), USAGE_MSG);
    fprintf(fh, "\nSWITCHES:\n");
    skOptionsDefaultUsage(fh);

    for (i = 0; appOptions[i].name; i++ ) {
        fprintf(fh, "--%s %s. ", appOptions[i].name,
                SK_OPTION_HAS_ARG(appOptions[i]));
        switch (appOptions[i].val) {
          case OPT_FIELDS:
            /* Dynamically build the help */
            usageFields(fh);
            break;
          default:
            /* Simple static help text from the appHelp array */
            fprintf(fh, "%s\n", appHelp[i]);
            break;
        }
    }

    skOptionsCtxOptionsUsage(optctx, fh);
}


/*
 *  appTeardown()
 *
 *    Teardown all modules, close all files, and tidy up all
 *    application state.
 *
 *    This function is idempotent.
 */
static void appTeardown(void)
{
    static int teardownFlag = 0;

    if (teardownFlag) {
        return;
    }
    teardownFlag = 1;

#error "Anything you put in setup should now be torn down"
    /* for example, close sample output file */
    skStreamDestroy(&out_ios);

    skAppUnregister();
}


/*
 *  appSetup(argc, argv);
 *
 *    Perform all the setup for this application include setting up
 *    required modules, parsing options, etc.  This function should be
 *    passed the same arguments that were passed into main().
 *
 *    Returns to the caller if all setup succeeds.  If anything fails,
 *    this function will cause the application to exit with a FAILURE
 *    exit status.
 */
static void appSetup(int argc, char **argv)
{
    SILK_FEATURES_DEFINE_STRUCT(features);
    int rv;

    /* verify same number of options and help strings */
    assert((sizeof(appHelp)/sizeof(char *)) ==
           (sizeof(appOptions)/sizeof(struct option)));

    /* register the application */
    skAppRegister(argv[0]);
    skAppVerifyFeatures(&features, NULL);
    skOptionsSetUsageCallback(&appUsageLong);

    /* initialize globals */
#error "Initialize any global variables here"
    /* for example: set global output to NULL */
    out_ios = NULL;

    /* register the options */
    if (skOptionsRegister(appOptions, &appOptionsHandler, NULL)
        || sksiteOptionsRegister(SK_SITE_FLAG_CONFIG_FILE))
    {
        skAppPrintErr("Unable to register options");
        exit(EXIT_FAILURE);
    }

#error "Do any other module setup here"

    /* parse the options */
    arg_index = skOptionsParse(argc, argv);
    if (arg_index < 0) {
        /* options parsing should print error */
        skAppUsage();           /* never returns */
    }

    /* try to load site config file; if it fails, we will not be able
     * to resolve flowtype and sensor from input file names */
    sksiteConfigure(0);

#error "Do any options validation here"

#error "If you expect filenames on command line keep this:"
    /* arg_index is looking at first file name to process */
    if (arg_index == argc) {
        if (FILEIsATty(stdin)) {
            skAppPrintErr("No input files on command line and"
                          " stdin is connected to a terminal");
            skAppUsage();       /* never returns */
        }
    }

#error "If you do NOT expect filenames on command line, keep this:"
    /* check for extraneous arguments */
    if (arg_index != argc) {
        skAppPrintErr("Too many arguments or unrecognized switch '%s'",
                      argv[arg_index]);
        skAppUsage();           /* never returns */
    }

#error "Once all options are set, open input and output"
    /* for example, open a SiLK flow file as an output file */
    rv = skStreamOpenSilkFlow(&out_ios, output_path, SK_IO_WRITE);
    if (rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
        skAppPrintErr("Unable to open output file. Exiting");
        skStreamDestroy(&out_ios);
        exit(EXIT_FAILURE);
    }

    if (atexit(appTeardown) < 0) {
        skAppPrintErr("Unable to register appTeardown() with atexit()");
        appTeardown();
        exit(EXIT_FAILURE);
    }

    return;  /* OK */
}


/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int appOptionsHandler(
    clientData  UNUSED(cData),
    int         opt_index,
    char       *opt_arg)
{
    int rv;

    switch ((appOptionsEnum)opt_index) {
#error "Add options handling here.  Return 1 on failure."

      case OPT_FIRST:           /* remove when real options added */
        /* do something with the argument to the switch; for example,
         * parse as an integer */
        rv = skStringParseUint32(&value, opt_arg, 0, 0);
        if (rv) {
            skAppPrintErr("Invalid %s '%s': %s",
                          appOptions[opt_index].name, opt_arg,
                          skStringParseStrerror(rv));
            return 1;
        }
        break;

      case OPT_SECOND:          /* remove when real options added */
        /* set a flag based on this option */
        flag = 1;
        break;
    }

    return 0;  /* OK */
}


/*
 *  rwios = appNextInput(argc, argv);
 *
 *    Open and return the next input file from the command line or the
 *    standard input if no files were given on the command line.
 */
static skstream_t *appNextInput(int argc, char **argv)
{
    static int initialized = 0;
    skstream_t *rwios = NULL;
    const char *fname = NULL;
    int rv;

    if (arg_index < argc) {
        /* get current file and prepare to get next */
        fname = argv[arg_index];
        ++arg_index;
    } else {
        if (initialized) {
            /* no more input */
            return NULL;
        }
        /* input is from stdin */
        fname = "stdin";
    }

    initialized = 1;

    /* create rwios and open file */
    rv = skStreamOpenSilkFlow(&rwios, fname, SK_IO_READ);
    if (rv) {
        skStreamPrintLastErr(rwios, rv, NULL);
        skStreamDestroy(&rwios);
    }

    return rwios;
}


int main(int argc, char **argv)
{
    skstream_t *in_ios;
    int in_rv = SKSTREAM_OK;
    int rv = SKSTREAM_OK;

    appSetup(argc, argv);                       /* never returns on error */

#error "Loop over files on command line or read from stdin."
#error "Process each file, preferably in a separate function."
    /* For each input, process each record */
    while (NULL != (in_ios = appNextInput(argc, argv))) {
        while ((in_rv = skStreamReadRecord(in_ios, &rwrec)) == SKSTREAM_OK) {
            /* process record */
            rv = skStreamWriteRecord(out_ios, &rwrec);
            if (SKSTREAM_OK != rv) {
                skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
                skStreamDestroy(&in_ios);
                goto END;
            }
        }
        if (SKSTREAM_ERR_EOF != in_rv) {
            skStreamPrintLastErr(in_ios, in_rv, &skAppPrintErr);
        }
        skStreamDestroy(&in_ios);
    }

    rv = skStreamClose(out_ios);
    if (SKSTREAM_OK != rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
    }

  END:
    return ((SKSTREAM_OK == rv) ? EXIT_SUCCESS : EXIT_FAILURE);
}


/*
** Local Variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/

[-- Attachment #3: Type: text/plain, Size: 42 bytes --]


-- 
Michael Welsh Duggan
(md5i@md5i.com)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-09-20 15:25 bug#9560: 24.0.50; c-mode syntax problems Michael Welsh Duggan
                   ` (2 preceding siblings ...)
  2011-10-10  4:15 ` bug#9560: Cache information during failure Michael Welsh Duggan
@ 2011-10-13  2:33 ` Michael Welsh Duggan
  2011-10-19 10:16   ` Alan Mackenzie
  2011-10-22 11:26 ` bug#9560: Bug #9560 fixed Alan Mackenzie
  4 siblings, 1 reply; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-10-13  2:33 UTC (permalink / raw)
  To: 9560

[-- Attachment #1: Type: text/plain, Size: 146 bytes --]

From emacs -Q:

Do NOT resize the frame.  The recipe includes C-v, which depends on the
window (and hence frame) size.

Load the following file:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: rwsiteinfo-backup.c --]
[-- Type: text/x-csrc, Size: 14006 bytes --]

/*
** Copyright (C) 2011 by Carnegie Mellon University.
**
** @OPENSOURCE_HEADER_START@
**
** Use of the SILK system and related source code is subject to the terms
** of the following licenses:
**
** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
**
** NO WARRANTY
**
** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
** DELIVERABLES UNDER THIS LICENSE.
**
** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
** Mellon University, its trustees, officers, employees, and agents from
** all claims or demands made against them (and any related losses,
** expenses, or attorney's fees) arising out of, or relating to Licensee's
** and/or its sub licensees' negligent use or willful misuse of or
** negligent conduct or willful misconduct regarding the Software,
** facilities, or other rights or assistance granted by Carnegie Mellon
** University under this License, including, but not limited to, any
** claims of product liability, personal injury, death, damage to
** property, or violation of any laws or regulations.
**
** Carnegie Mellon University Software Engineering Institute authored
** documents are sponsored by the U.S. Department of Defense under
** Contract FA8721-05-C-0003. Carnegie Mellon University retains
** copyrights in all material produced under this contract. The U.S.
** Government retains a non-exclusive, royalty-free license to publish or
** reproduce these documents, or allow others to do so, for U.S.
** Government purposes only pursuant to the copyright license under the
** contract clause at 252.227.7013.
**
** @OPENSOURCE_HEADER_END@
*/

/*
**  Prints information about SiLK site configurations
**
**  Michael Duggan
**  September 2011
*/


#include <silk/silk.h>

RCSIDENT("$Id$");

#include <silk/skstream.h>
#include <silk/skstringmap.h>
#include <silk/sksite.h>
#include <silk/utils.h>


/* LOCAL DEFINES AND TYPEDEFS */

/* where to write --help output */
#define USAGE_FH stdout


/* LOCAL VARIABLE DEFINITIONS */
typedef enum {
    RWST_CLASS,
    RWST_TYPE,
    RWST_FLOWTYPE,
    RWST_FLOWTYPE_ID,
    RWST_SENSOR,
    RWST_SENSOR_ID,
    RWST_SENSOR_DESC,
    RWST_DEFAULT_CLASS,
    RWST_DEFAULT_TYPE,
    RWST_MARK_DEFAULTS,
    RWST_CLASS_LIST,
    RWST_TYPE_LIST,
    RWST_FLOWTYPE_LIST,
    RWST_FLOWTYPE_ID_LIST,
    RWST_SENSOR_LIST,
    RWST_SENSOR_ID_LIST,
    RWST_DEFAULT_CLASS_LIST,
    RWST_DEFAULT_TYPE_LIST
} rws_type_t;


static const sk_stringmap_entry_t field_map_entries[] = {
    {"class",    RWST_CLASS,     "class name",    NULL},
    {"type",     RWST_TYPE,      "type name",     NULL},
    {"flowtype", RWST_FLOWTYPE,  "flowtype name", NULL},
    {"id-flowtype", RWST_FLOWTYPE_ID, "flowtype integer identifier", NULL},
    {"sensor", RWST_SENSOR, "sensor name", NULL},
    {"id-sensor", RWST_SENSOR_ID, "sensor integer identifier", NULL},
    {"describe-sensor", RWST_SENSOR_DESC, "sensor description", NULL},
    {"default-class", RWST_DEFAULT_CLASS, "default class name", NULL},
    {"default-type", RWST_DEFAULT_TYPE, "default type name", NULL},
    {"mark-defaults", RWST_MARK_DEFAULTS,
     "'+' for default classes, '*' for types", NULL},
};


/* OPTIONS SETUP */

typedef enum {
    OPT_NO_TITLES, OPT_NO_COLUMNS, OPT_COLUMN_SEPARATOR,
    OPT_NO_FINAL_DELIMITER, OPT_DELIMITED,
    OPT_OUTPUT_PATH, OPT_PAGER
} appOptionsEnum;

static struct option appOptions[] = {
    {"no-titles",           NO_ARG,       0, OPT_NO_TITLES},
    {"no-columns",          NO_ARG,       0, OPT_NO_COLUMNS},
    {"column-separator",    REQUIRED_ARG, 0, OPT_COLUMN_SEPARATOR},
    {"no-final-delimiter",  NO_ARG,       0, OPT_NO_FINAL_DELIMITER},
    {"delimited",           OPTIONAL_ARG, 0, OPT_DELIMITED},
    {"output-path",         REQUIRED_ARG, 0, OPT_OUTPUT_PATH},
    {"pager",               REQUIRED_ARG, 0, OPT_PAGER},
    {0,0,0,0}               /* sentinel entry */
    {0,0,0,0}           /* sentinel entry */
};

static const char *appHelp[] = {
    "Do not print column headers. Def. Print titles.",
    "Disable fixed-width columnar output. Def. Columnar",
    "Use specified character between columns. Def. '|'",
    "Suppress column delimiter at end of line. Def. No",
    "Shortcut for --no-columns --no-final-del --column-sep=CHAR",
    "Send output to given file path. Def. stdout",
    "Program to invoke to page output. Def. $SILK_PAGER or $PAGER",
    (char *)NULL
};



/* LOCAL FUNCTION PROTOTYPES */

static void appUsageLong(void);
static void appTeardown(void);
static void appSetup(int argc, char **argv);
static int  appOptionsHandler(clientData cData, int opt_index, char *opt_arg);


/* FUNCTION DEFINITIONS */

/*
 *  appUsageLong();
 *
 *    Print complete usage information to USAGE_FH.  Pass this
 *    function to skOptionsSetUsageCallback(); skOptionsParse() will
 *    call this funciton and then exit the program when the --help
 *    option is given.
 */
static void appUsageLong(void)
{
#define USAGE_MSG                                                       \
    ("<SWITCHES>\n"                                                     \
     "\tOutputs information about a SiLK site configuration.\n")

    FILE *fh = USAGE_FH;
    int i;

    fprintf(fh, "%s %s", skAppName(), USAGE_MSG);
    fprintf(fh, "\nSWITCHES:\n");
    skOptionsDefaultUsage(fh);

    for (i = 0; appOptions[i].name; i++ ) {
        fprintf(fh, "--%s %s. ", appOptions[i].name,
                SK_OPTION_HAS_ARG(appOptions[i]));
        switch (appOptions[i].val) {
          case OPT_FIELDS:
            /* Dynamically build the help */
            usageFields(fh);
            break;
          default:
            /* Simple static help text from the appHelp array */
            fprintf(fh, "%s\n", appHelp[i]);
            break;
        }
    }

    skOptionsCtxOptionsUsage(optctx, fh);
}


/*
 *  appTeardown()
 *
 *    Teardown all modules, close all files, and tidy up all
 *    application state.
 *
 *    This function is idempotent.
 */
static void appTeardown(void)
{
    static int teardownFlag = 0;

    if (teardownFlag) {
        return;
    }
    teardownFlag = 1;

#error "Anything you put in setup should now be torn down"
    /* for example, close sample output file */
    skStreamDestroy(&out_ios);

    skAppUnregister();
}


/*
 *  appSetup(argc, argv);
 *
 *    Perform all the setup for this application include setting up
 *    required modules, parsing options, etc.  This function should be
 *    passed the same arguments that were passed into main().
 *
 *    Returns to the caller if all setup succeeds.  If anything fails,
 *    this function will cause the application to exit with a FAILURE
 *    exit status.
 */
static void appSetup(int argc, char **argv)
{
    SILK_FEATURES_DEFINE_STRUCT(features);
    int rv;

    /* verify same number of options and help strings */
    assert((sizeof(appHelp)/sizeof(char *)) ==
           (sizeof(appOptions)/sizeof(struct option)));

    /* register the application */
    skAppRegister(argv[0]);
    skAppVerifyFeatures(&features, NULL);
    skOptionsSetUsageCallback(&appUsageLong);

    /* initialize globals */
#error "Initialize any global variables here"
    /* for example: set global output to NULL */
    out_ios = NULL;

    /* register the options */
    if (skOptionsRegister(appOptions, &appOptionsHandler, NULL)
        || sksiteOptionsRegister(SK_SITE_FLAG_CONFIG_FILE))
    {
        skAppPrintErr("Unable to register options");
        exit(EXIT_FAILURE);
    }

#error "Do any other module setup here"

    /* parse the options */
    arg_index = skOptionsParse(argc, argv);
    if (arg_index < 0) {
        /* options parsing should print error */
        skAppUsage();           /* never returns */
    }

    /* try to load site config file; if it fails, we will not be able
     * to resolve flowtype and sensor from input file names */
    sksiteConfigure(0);

#error "Do any options validation here"

#error "If you expect filenames on command line keep this:"
    /* arg_index is looking at first file name to process */
    if (arg_index == argc) {
        if (FILEIsATty(stdin)) {
            skAppPrintErr("No input files on command line and"
                          " stdin is connected to a terminal");
            skAppUsage();       /* never returns */
        }
    }

#error "If you do NOT expect filenames on command line, keep this:"
    /* check for extraneous arguments */
    if (arg_index != argc) {
        skAppPrintErr("Too many arguments or unrecognized switch '%s'",
                      argv[arg_index]);
        skAppUsage();           /* never returns */
    }

#error "Once all options are set, open input and output"
    /* for example, open a SiLK flow file as an output file */
    rv = skStreamOpenSilkFlow(&out_ios, output_path, SK_IO_WRITE);
    if (rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
        skAppPrintErr("Unable to open output file. Exiting");
        skStreamDestroy(&out_ios);
        exit(EXIT_FAILURE);
    }

    if (atexit(appTeardown) < 0) {
        skAppPrintErr("Unable to register appTeardown() with atexit()");
        appTeardown();
        exit(EXIT_FAILURE);
    }

    return;  /* OK */
}


/*
 *  status = appOptionsHandler(cData, opt_index, opt_arg);
 *
 *    This function is passed to skOptionsRegister(); it will be called
 *    by skOptionsParse() for each user-specified switch that the
 *    application has registered; it should handle the switch as
 *    required---typically by setting global variables---and return 1
 *    if the switch processing failed or 0 if it succeeded.  Returning
 *    a non-zero from from the handler causes skOptionsParse() to return
 *    a negative value.
 *
 *    The clientData in 'cData' is typically ignored; 'opt_index' is
 *    the index number that was specified as the last value for each
 *    struct option in appOptions[]; 'opt_arg' is the user's argument
 *    to the switch for options that have a REQUIRED_ARG or an
 *    OPTIONAL_ARG.
 */
static int appOptionsHandler(
    clientData  UNUSED(cData),
    int         opt_index,
    char       *opt_arg)
{
    int rv;

    switch ((appOptionsEnum)opt_index) {
#error "Add options handling here.  Return 1 on failure."

      case OPT_FIRST:           /* remove when real options added */
        /* do something with the argument to the switch; for example,
         * parse as an integer */
        rv = skStringParseUint32(&value, opt_arg, 0, 0);
        if (rv) {
            skAppPrintErr("Invalid %s '%s': %s",
                          appOptions[opt_index].name, opt_arg,
                          skStringParseStrerror(rv));
            return 1;
        }
        break;

      case OPT_SECOND:          /* remove when real options added */
        /* set a flag based on this option */
        flag = 1;
        break;
    }

    return 0;  /* OK */
}


/*
 *  rwios = appNextInput(argc, argv);
 *
 *    Open and return the next input file from the command line or the
 *    standard input if no files were given on the command line.
 */
static skstream_t *appNextInput(int argc, char **argv)
{
    static int initialized = 0;
    skstream_t *rwios = NULL;
    const char *fname = NULL;
    int rv;

    if (arg_index < argc) {
        /* get current file and prepare to get next */
        fname = argv[arg_index];
        ++arg_index;
    } else {
        if (initialized) {
            /* no more input */
            return NULL;
        }
        /* input is from stdin */
        fname = "stdin";
    }

    initialized = 1;

    /* create rwios and open file */
    rv = skStreamOpenSilkFlow(&rwios, fname, SK_IO_READ);
    if (rv) {
        skStreamPrintLastErr(rwios, rv, NULL);
        skStreamDestroy(&rwios);
    }

    return rwios;
}


int main(int argc, char **argv)
{
    skstream_t *in_ios;
    int in_rv = SKSTREAM_OK;
    int rv = SKSTREAM_OK;

    appSetup(argc, argv);                       /* never returns on error */

#error "Loop over files on command line or read from stdin."
#error "Process each file, preferably in a separate function."
    /* For each input, process each record */
    while (NULL != (in_ios = appNextInput(argc, argv))) {
        while ((in_rv = skStreamReadRecord(in_ios, &rwrec)) == SKSTREAM_OK) {
            /* process record */
            rv = skStreamWriteRecord(out_ios, &rwrec);
            if (SKSTREAM_OK != rv) {
                skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
                skStreamDestroy(&in_ios);
                goto END;
            }
        }
        if (SKSTREAM_ERR_EOF != in_rv) {
            skStreamPrintLastErr(in_ios, in_rv, &skAppPrintErr);
        }
        skStreamDestroy(&in_ios);
    }

    rv = skStreamClose(out_ios);
    if (SKSTREAM_OK != rv) {
        skStreamPrintLastErr(out_ios, rv, &skAppPrintErr);
    }

  END:
    return ((SKSTREAM_OK == rv) ? EXIT_SUCCESS : EXIT_FAILURE);
}


/*
** Local Variables:
** mode:c
** indent-tabs-mode:nil
** c-basic-offset:4
** End:
*/

[-- Attachment #3: Type: text/plain, Size: 116 bytes --]


Type:

  M-x edit-kbd-macro RET y C-x e C-x h C-w C-x i

When prompted, insert the following keyboard macro file:


[-- Attachment #4: c-mode.macro --]
[-- Type: application/octet-stream, Size: 12394 bytes --]

;; Keyboard Macro Editor.  Press C-c C-c to finish; press C-x k RET to cancel.
;; Original keys: 3*C-v 7*C-n 21*C-k TAB { "class" , SPC RWST_C M-/ M-DEL DEL , SPC "class SPC name" , SPC NULL } , RET TAB { "type" , SPC RWST_T M-/ M-DEL DEL , SPC "type SPC name" , SPC NULL } , RET TAB { "flowtype , SPC "RWST_FLO M-/ 2*M-DEL DEL , SPC "flowtype SPC name" , SPC NULL } , RET TAB { "sensor" , SPC C-p 2*C-f , 4*DEL " , . DEL SPC C-n RWST_SE M-/ 2*M-DEL DEL , . DEL SPC "sensor SPC name" , SPC NULL } C-p C-e RET TAB { "id-flowtype" , SPC RWST_FL M-/ _ M-/ M-DEL DEL , SPC "flowtype SPC integer SPC ide M-/ M-DEL identifier" , SPC NULL } , C-n , RET TAB { "id-sensor" , SPC RST_SE 5*DEL WST_SE M-/ _ M-/ M-DEL DEL , SPC "sensor SPC integer SPC ident M-/ " , . DEL SPC NULL } , RET TAB { "dexfrib 5*DEL scribe-senro 2*DEL or" , SPC RWST_SE M-/ M-DEL D M-/ , SPC "sensor SPC desc M-/ 3*DEL iption" , SPC NULL } , RET TAB { "default-class" , SPC RWST_DRF 2*DEL EDF 2*DEL F M-/ 2*M-DEL C M-/ M-DEL DEL , SPC "default SPC class SPC name" , SPC NULL } , RET TAB { "default-type" , SPC RWST_DE 2*M-/ M-DEL DEL , SPC "default SPC type SPC name" , SPC NULL } , RET TAB { "mark-defaults" , SPC RWS_ DEL T_MA M-/ , SPC DEL RET TAB "'+' SPC for SPC default SPC classes , SPC ' * ' SPC for SPC types" , SPC N U L : DEL L } , RET TAB { "class : list" , SPC RST DEL <S-backspace> WST_CLA 2*M-/ , SPC "list SPC of SPC class SPC names" , SPC NULL } , RET TAB { "type : list" , SPC RWST_TY M-/ _L M-/ , SPC "list SPC of SPC type SPC names" , SPC NULL } , RET TAB { "flowtype : list" , SPC REST_FL DEL 2*M-DEL RWST_FL M-/ M-DEL M-l 4*C-p C-e L M-/ , SPC "list SPC of SPC flowtype SPC names" , SPC NULL } , RET 2*TAB

Command: last-kbd-macro
Key: none

Macro:

3*C-v			;; scroll-up-command
7*C-n			;; next-line
21*C-k			;; kill-line
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"class"			;; self-insert-command * 7
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_C			;; self-insert-command * 6
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"class			;; self-insert-command * 6
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"type"			;; self-insert-command * 6
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_T			;; self-insert-command * 6
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"type			;; self-insert-command * 5
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"flowtype		;; self-insert-command * 9
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"RWST_FLO		;; self-insert-command * 9
M-/			;; dabbrev-expand
2*M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"flowtype		;; self-insert-command * 9
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"sensor"		;; self-insert-command * 8
,			;; c-electric-semi&comma
SPC			;; self-insert-command
C-p			;; previous-line
2*C-f			;; forward-char
,			;; c-electric-semi&comma
4*DEL			;; c-electric-backspace
"			;; self-insert-command
,			;; c-electric-semi&comma
.			;; self-insert-command
DEL			;; c-electric-backspace
SPC			;; self-insert-command
C-n			;; next-line
RWST_SE			;; self-insert-command * 7
M-/			;; dabbrev-expand
2*M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
.			;; self-insert-command
DEL			;; c-electric-backspace
SPC			;; self-insert-command
"sensor			;; self-insert-command * 7
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
C-p			;; previous-line
C-e			;; move-end-of-line
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"id-flowtype"		;; self-insert-command * 13
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_FL			;; self-insert-command * 7
M-/			;; dabbrev-expand
_			;; self-insert-command
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"flowtype		;; self-insert-command * 9
SPC			;; self-insert-command
integer			;; self-insert-command * 7
SPC			;; self-insert-command
ide			;; self-insert-command * 3
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
identifier"		;; self-insert-command * 11
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
C-n			;; next-line
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"id-sensor"		;; self-insert-command * 11
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RST_SE			;; self-insert-command * 6
5*DEL			;; c-electric-backspace
WST_SE			;; self-insert-command * 6
M-/			;; dabbrev-expand
_			;; self-insert-command
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"sensor			;; self-insert-command * 7
SPC			;; self-insert-command
integer			;; self-insert-command * 7
SPC			;; self-insert-command
ident			;; self-insert-command * 5
M-/			;; dabbrev-expand
"			;; self-insert-command
,			;; c-electric-semi&comma
.			;; self-insert-command
DEL			;; c-electric-backspace
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"dexfrib		;; self-insert-command * 8
5*DEL			;; c-electric-backspace
scribe-senro		;; self-insert-command * 12
2*DEL			;; c-electric-backspace
or"			;; self-insert-command * 3
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_SE			;; self-insert-command * 7
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
D			;; self-insert-command
M-/			;; dabbrev-expand
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"sensor			;; self-insert-command * 7
SPC			;; self-insert-command
desc			;; self-insert-command * 4
M-/			;; dabbrev-expand
3*DEL			;; c-electric-backspace
iption"			;; self-insert-command * 7
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"default-class"		;; self-insert-command * 15
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_DRF		;; self-insert-command * 8
2*DEL			;; c-electric-backspace
EDF			;; self-insert-command * 3
2*DEL			;; c-electric-backspace
F			;; self-insert-command
M-/			;; dabbrev-expand
2*M-DEL			;; backward-kill-word
C			;; self-insert-command
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"default		;; self-insert-command * 8
SPC			;; self-insert-command
class			;; self-insert-command * 5
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"default-type"		;; self-insert-command * 14
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_DE			;; self-insert-command * 7
2*M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
DEL			;; c-electric-backspace
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"default		;; self-insert-command * 8
SPC			;; self-insert-command
type			;; self-insert-command * 4
SPC			;; self-insert-command
name"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"mark-defaults"		;; self-insert-command * 15
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWS_			;; self-insert-command * 4
DEL			;; c-electric-backspace
T_MA			;; self-insert-command * 4
M-/			;; dabbrev-expand
,			;; c-electric-semi&comma
SPC			;; self-insert-command
DEL			;; c-electric-backspace
RET			;; newline
TAB			;; c-indent-line-or-region
"'+'			;; self-insert-command * 4
SPC			;; self-insert-command
for			;; self-insert-command * 3
SPC			;; self-insert-command
default			;; self-insert-command * 7
SPC			;; self-insert-command
classes			;; self-insert-command * 7
,			;; c-electric-semi&comma
SPC			;; self-insert-command
'			;; self-insert-command
*			;; c-electric-star
'			;; self-insert-command
SPC			;; self-insert-command
for			;; self-insert-command * 3
SPC			;; self-insert-command
types"			;; self-insert-command * 6
,			;; c-electric-semi&comma
SPC			;; self-insert-command
N U L			;; self-insert-command * 3
:			;; c-electric-colon
DEL			;; c-electric-backspace
L			;; self-insert-command
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"class			;; self-insert-command * 6
:			;; c-electric-colon
list"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RST			;; self-insert-command * 3
DEL			;; c-electric-backspace
<S-backspace>
WST_CLA			;; self-insert-command * 7
2*M-/			;; dabbrev-expand
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"list			;; self-insert-command * 5
SPC			;; self-insert-command
of			;; self-insert-command * 2
SPC			;; self-insert-command
class			;; self-insert-command * 5
SPC			;; self-insert-command
names"			;; self-insert-command * 6
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"type			;; self-insert-command * 5
:			;; c-electric-colon
list"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
RWST_TY			;; self-insert-command * 7
M-/			;; dabbrev-expand
_L			;; self-insert-command * 2
M-/			;; dabbrev-expand
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"list			;; self-insert-command * 5
SPC			;; self-insert-command
of			;; self-insert-command * 2
SPC			;; self-insert-command
type			;; self-insert-command * 4
SPC			;; self-insert-command
names"			;; self-insert-command * 6
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
TAB			;; c-indent-line-or-region
{			;; c-electric-brace
"flowtype		;; self-insert-command * 9
:			;; c-electric-colon
list"			;; self-insert-command * 5
,			;; c-electric-semi&comma
SPC			;; self-insert-command
REST_FL			;; self-insert-command * 7
DEL			;; c-electric-backspace
2*M-DEL			;; backward-kill-word
RWST_FL			;; self-insert-command * 7
M-/			;; dabbrev-expand
M-DEL			;; backward-kill-word
M-l			;; downcase-word
4*C-p			;; previous-line
C-e			;; move-end-of-line
L			;; self-insert-command
M-/			;; dabbrev-expand
,			;; c-electric-semi&comma
SPC			;; self-insert-command
"list			;; self-insert-command * 5
SPC			;; self-insert-command
of			;; self-insert-command * 2
SPC			;; self-insert-command
flowtype		;; self-insert-command * 8
SPC			;; self-insert-command
names"			;; self-insert-command * 6
,			;; c-electric-semi&comma
SPC			;; self-insert-command
NULL			;; self-insert-command * 4
}			;; c-electric-brace
,			;; c-electric-semi&comma
RET			;; newline
2*TAB			;; c-indent-line-or-region

[-- Attachment #5: Type: text/plain, Size: 913 bytes --]


Type:

  C-c C-c

You should be back at rwsiteinfo-backup.c.  Execute the macro using:

  C-x e

Then type:

  TAB

At this point, you should see the indentation move to just under the `o'
in "flowtype:list".  This location is incorrect.  If you then do the
following:

  M-x set-variable RET c-echo-syntactic-information-p RET t RET TAB

you will see that c-mode believes the syntax at that point to be
topmost-intro-cont instead of the proper brace-list-entry.

When you have solved this bug, please let me know if the solution has a
reasonable chance of having solved the other problem that I have not
been able to recreate reliably, which is getting "topmost-intro indent
0" instead of "statement indent 4" when in the middle of editing a
function.  If these have little chance of being connected, I'll do my
best to try to create that scenario again (no promises).

-- 
Michael Welsh Duggan
(md5i@md5i.com)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-10-13  2:33 ` bug#9560: An exact recipe Michael Welsh Duggan
@ 2011-10-19 10:16   ` Alan Mackenzie
  2011-10-19 13:45     ` Michael Welsh Duggan
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Mackenzie @ 2011-10-19 10:16 UTC (permalink / raw)
  To: Michael Welsh Duggan; +Cc: 9560

Hi, Michael.

On Wed, Oct 12, 2011 at 10:33:22PM -0400, Michael Welsh Duggan wrote:
> >>>From emacs -Q:

> Do NOT resize the frame.  The recipe includes C-v, which depends on the
> window (and hence frame) size.

> Load the following file:

[ .... ]


> Type:

>   M-x edit-kbd-macro RET y C-x e C-x h C-w C-x i

> When prompted, insert the following keyboard macro file:

[ .... ]


> Type:

>   C-c C-c

> You should be back at rwsiteinfo-backup.c.  Execute the macro using:

>   C-x e

> Then type:

>   TAB

OK, I've got about this far.  I've been busy getting 5.32.2 into XEmacs.
The first thing I'm going to do with this macro is replace the C-v's with
an equivalent number of C-n's, because my frames on a tty are a fixed 65
lines (not including mode line and minibuffer) high.  :-)

Emacs's facilities for keyboard macros are not comfortable.

> At this point, you should see the indentation move to just under the `o'
> in "flowtype:list".  This location is incorrect.  If you then do the
> following:

>   M-x set-variable RET c-echo-syntactic-information-p RET t RET TAB

> you will see that c-mode believes the syntax at that point to be
> topmost-intro-cont instead of the proper brace-list-entry.

> When you have solved this bug, please let me know if the solution has a
> reasonable chance of having solved the other problem that I have not
> been able to recreate reliably, which is getting "topmost-intro indent
> 0" instead of "statement indent 4" when in the middle of editing a
> function.  If these have little chance of being connected, I'll do my
> best to try to create that scenario again (no promises).

> -- 
> Michael Welsh Duggan
> (md5i@md5i.com)

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-10-19 10:16   ` Alan Mackenzie
@ 2011-10-19 13:45     ` Michael Welsh Duggan
  2011-10-19 17:39       ` Alan Mackenzie
  2011-10-20 11:42       ` Alan Mackenzie
  0 siblings, 2 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-10-19 13:45 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: 9560

Alan Mackenzie <acm@muc.de> writes:

> Hi, Michael.
>
> On Wed, Oct 12, 2011 at 10:33:22PM -0400, Michael Welsh Duggan wrote:
>> >>>From emacs -Q:
>
>> Do NOT resize the frame.  The recipe includes C-v, which depends on the
>> window (and hence frame) size.
>
>> Load the following file:
>
> [ .... ]
>
>
>> Type:
>
>>   M-x edit-kbd-macro RET y C-x e C-x h C-w C-x i
>
>> When prompted, insert the following keyboard macro file:
>
> [ .... ]
>
>
>> Type:
>
>>   C-c C-c
>
>> You should be back at rwsiteinfo-backup.c.  Execute the macro using:
>
>>   C-x e
>
>> Then type:
>
>>   TAB
>
> OK, I've got about this far.  I've been busy getting 5.32.2 into XEmacs.
> The first thing I'm going to do with this macro is replace the C-v's with
> an equivalent number of C-n's, because my frames on a tty are a fixed 65
> lines (not including mode line and minibuffer) high.  :-)
>
> Emacs's facilities for keyboard macros are not comfortable.

Okay, I've done some experimenting, and unfortunately, I have been
unable to recreate this problem using this recipe using emacs -Q -nw.
I've only encountered it using an X window.  In this environment, I was
able to recreate the problem consistently.  I was able to replace the
initial "3*C-v 7*C-n" in the macro with "100*C-n C-l" and this allowed
it to work with larger frame sizes.  Don't ask me why the C-l is
necessary, as I do not know.

>> At this point, you should see the indentation move to just under the `o'
>> in "flowtype:list".  This location is incorrect.  If you then do the
>> following:
>
>>   M-x set-variable RET c-echo-syntactic-information-p RET t RET TAB
>
>> you will see that c-mode believes the syntax at that point to be
>> topmost-intro-cont instead of the proper brace-list-entry.
>
>> When you have solved this bug, please let me know if the solution has a
>> reasonable chance of having solved the other problem that I have not
>> been able to recreate reliably, which is getting "topmost-intro indent
>> 0" instead of "statement indent 4" when in the middle of editing a
>> function.  If these have little chance of being connected, I'll do my
>> best to try to create that scenario again (no promises).
>
>> -- 
>> Michael Welsh Duggan
>> (md5i@md5i.com)

-- 
Michael Welsh Duggan
(md5i@md5i.com)





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-10-19 13:45     ` Michael Welsh Duggan
@ 2011-10-19 17:39       ` Alan Mackenzie
  2011-10-20 11:42       ` Alan Mackenzie
  1 sibling, 0 replies; 11+ messages in thread
From: Alan Mackenzie @ 2011-10-19 17:39 UTC (permalink / raw)
  To: Michael Welsh Duggan; +Cc: 9560

Hi again, Michael.

On Wed, Oct 19, 2011 at 09:45:45AM -0400, Michael Welsh Duggan wrote:
> Alan Mackenzie <acm@muc.de> writes:

> Okay, I've done some experimenting, and unfortunately, I have been
> unable to recreate this problem using this recipe using emacs -Q -nw.
> I've only encountered it using an X window.

I found that too, on a tty - it's rather worrying.  ;-(

> In this environment, I was able to recreate the problem consistently.
> I was able to replace the initial "3*C-v 7*C-n" in the macro with
> "100*C-n C-l" and this allowed it to work with larger frame sizes.
> Don't ask me why the C-l is necessary, as I do not know.

I can now reproduce the problem consistently.

As you surmised, the problem is in `c-state-cache', the cache of braces,
parens, and brackets which is essential to CC Mode's operation.

I'll see if I can get some instrumentation on `c-parse-state' so as to
track down the exact point the cache is going wrong.  I do hope such
instrumentation won't make the error go away.

> -- 
> Michael Welsh Duggan
> (md5i@md5i.com)

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-10-19 13:45     ` Michael Welsh Duggan
  2011-10-19 17:39       ` Alan Mackenzie
@ 2011-10-20 11:42       ` Alan Mackenzie
  2011-10-21  1:42         ` Michael Welsh Duggan
  1 sibling, 1 reply; 11+ messages in thread
From: Alan Mackenzie @ 2011-10-20 11:42 UTC (permalink / raw)
  To: Michael Welsh Duggan; +Cc: 9560

Hi, Michael.

On Wed, Oct 19, 2011 at 09:45:45AM -0400, Michael Welsh Duggan wrote:
> Alan Mackenzie <acm@muc.de> writes:

> Okay, I've done some experimenting, and unfortunately, I have been
> unable to recreate this problem using this recipe using emacs -Q -nw.
> I've only encountered it using an X window.

That still perplexes me.  I've got a fix, but the problem should have
appeared on a tty and a -nw too.

> In this environment, I was able to recreate the problem consistently.
> I was able to replace the initial "3*C-v 7*C-n" in the macro with
> "100*C-n C-l" and this allowed it to work with larger frame sizes.
> Don't ask me why the C-l is necessary, as I do not know.

> >> When you have solved this bug, please let me know if the solution has a
> >> reasonable chance of having solved the other problem that I have not
> >> been able to recreate reliably, which is getting "topmost-intro indent
> >> 0" instead of "statement indent 4" when in the middle of editing a
> >> function.  If these have little chance of being connected, I'll do my
> >> best to try to create that scenario again (no promises).

I think there's a good chance of that bug being fixed by the following
patch (no promises ;-).

The bug was a bit of carelessness on my part.  I'd done
  (unless (and T1 T2 T3) ...) 
, and in the body tested
  (and T1 (not T3))
, which is rubbish, since that says nothing about the state of T2.  T2
being the wrong way round was what caused the bug to show up.

Anyhow, here's the patch.  Only the first chunk is for the bug; the rest
of it is the superior instrumentation.  Let me know how this goes!


*** orig/cc-engine.el	2011-10-19 19:16:01.000000000 +0000
--- cc-engine.el	2011-10-20 11:22:15.000000000 +0000
***************
*** 2485,2491 ****
  		     (<= from (cdr c-state-brace-pair-desert)))
  	  ;; Only search what we absolutely need to:
  	  (if (and c-state-brace-pair-desert
! 		   (> from (cdr c-state-brace-pair-desert)))
  	      (narrow-to-region (cdr c-state-brace-pair-desert) (point-max)))
  
  	  ;; In the next pair of nested loops, the inner one moves back past a
--- 2485,2491 ----
  		     (<= from (cdr c-state-brace-pair-desert)))
  	  ;; Only search what we absolutely need to:
  	  (if (and c-state-brace-pair-desert
! 		   (eq cache-pos (car c-state-brace-pair-desert)))
  	      (narrow-to-region (cdr c-state-brace-pair-desert) (point-max)))
  
  	  ;; In the next pair of nested loops, the inner one moves back past a
***************
*** 3169,3174 ****
--- 3169,3204 ----
  (unless (fboundp 'c-real-parse-state)
    (fset 'c-real-parse-state (symbol-function 'c-parse-state)))
  (cc-bytecomp-defun c-real-parse-state)
+ 
+ (defvar c-parse-state-state nil)
+ (defun c-record-parse-state-state ()
+   (setq c-parse-state-state
+ 	(mapcar
+ 	 (lambda (arg)
+ 	   (cons arg (symbol-value arg)))
+ 	 '(c-state-cache
+ 	   c-state-cache-good-pos
+ 	   c-state-nonlit-pos-cache
+ 	   c-state-nonlit-pos-cache-limit
+ 	   c-state-brace-pair-desert
+ 	   c-state-point-min
+ 	   c-state-point-min-lit-type
+ 	   c-state-point-min-lit-start
+ 	   c-state-min-scan-pos
+ 	   c-state-old-cpp-beg
+ 	   c-state-old-cpp-end))))
+ (defun c-replay-parse-state-state ()
+   (let ((outstring "(setq "))
+     (mapc
+      (lambda (arg)
+        (setq outstring
+ 	     (concat outstring
+ 		     (format "  %s %s%s"
+ 			     (car arg) (if (atom (cdr arg)) "" "'") (cdr arg)))))
+      c-parse-state-state)
+     (setq outstring (concat outstring ")"))
+     (message outstring)))
+ 
  (defun c-debug-parse-state ()
    (let ((here (point)) (res1 (c-real-parse-state)) res2)
      (let ((c-state-cache nil)
***************
*** 3187,3201 ****
        ;; The cache can actually go further back due to the ad-hoc way
        ;; the first paren is found, so try to whack off a bit of its
        ;; start before complaining.
!       (save-excursion
! 	(goto-char (or (c-least-enclosing-brace res2) (point)))
! 	(c-beginning-of-defun-1)
! 	(while (not (or (bobp) (eq (char-after) ?{)))
! 	  (c-beginning-of-defun-1))
! 	(unless (equal (c-whack-state-before (point) res1) res2)
! 	  (message (concat "c-parse-state inconsistency at %s: "
! 			   "using cache: %s, from scratch: %s")
! 		   here res1 res2))))
      res1))
  
  (defun c-toggle-parse-state-debug (&optional arg)
--- 3217,3237 ----
        ;; The cache can actually go further back due to the ad-hoc way
        ;; the first paren is found, so try to whack off a bit of its
        ;; start before complaining.
!       ;; (save-excursion
!       ;; 	(goto-char (or (c-least-enclosing-brace res2) (point)))
!       ;; 	(c-beginning-of-defun-1)
!       ;; 	(while (not (or (bobp) (eq (char-after) ?{)))
!       ;; 	  (c-beginning-of-defun-1))
!       ;; 	(unless (equal (c-whack-state-before (point) res1) res2)
!       ;; 	  (message (concat "c-parse-state inconsistency at %s: "
!       ;; 			   "using cache: %s, from scratch: %s")
!       ;; 		   here res1 res2)))
!       (message (concat "c-parse-state inconsistency at %s: "
! 		       "using cache: %s, from scratch: %s")
! 	       here res1 res2)
!       (message "Old state:")
!       (c-replay-parse-state-state))
!     (c-record-parse-state-state)
      res1))
  
  (defun c-toggle-parse-state-debug (&optional arg)

> -- 
> Michael Welsh Duggan
> (md5i@md5i.com)

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: An exact recipe
  2011-10-20 11:42       ` Alan Mackenzie
@ 2011-10-21  1:42         ` Michael Welsh Duggan
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Welsh Duggan @ 2011-10-21  1:42 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: 9560

Alan Mackenzie <acm@muc.de> writes:

> Hi, Michael.
>
> On Wed, Oct 19, 2011 at 09:45:45AM -0400, Michael Welsh Duggan wrote:
>> Alan Mackenzie <acm@muc.de> writes:
>
>> Okay, I've done some experimenting, and unfortunately, I have been
>> unable to recreate this problem using this recipe using emacs -Q -nw.
>> I've only encountered it using an X window.
>
> That still perplexes me.  I've got a fix, but the problem should have
> appeared on a tty and a -nw too.

Indeed.  Could font-locking interfere at any point?

>> In this environment, I was able to recreate the problem consistently.
>> I was able to replace the initial "3*C-v 7*C-n" in the macro with
>> "100*C-n C-l" and this allowed it to work with larger frame sizes.
>> Don't ask me why the C-l is necessary, as I do not know.
>
>> >> When you have solved this bug, please let me know if the solution has a
>> >> reasonable chance of having solved the other problem that I have not
>> >> been able to recreate reliably, which is getting "topmost-intro indent
>> >> 0" instead of "statement indent 4" when in the middle of editing a
>> >> function.  If these have little chance of being connected, I'll do my
>> >> best to try to create that scenario again (no promises).
>
> I think there's a good chance of that bug being fixed by the following
> patch (no promises ;-).

We can always hope!

> The bug was a bit of carelessness on my part.  I'd done
>   (unless (and T1 T2 T3) ...) 
> , and in the body tested
>   (and T1 (not T3))
> , which is rubbish, since that says nothing about the state of T2.  T2
> being the wrong way round was what caused the bug to show up.
>
> Anyhow, here's the patch.  Only the first chunk is for the bug; the rest
> of it is the superior instrumentation.  Let me know how this goes!

Well, it certainly fixes things in my initial tests.  After checking in,
I would consider this bug closed.  I'll open up a new one if I notice
something weird in the future.

-- 
Michael Welsh Duggan
(md5i@md5i.com)





^ permalink raw reply	[flat|nested] 11+ messages in thread

* bug#9560: Bug #9560 fixed
  2011-09-20 15:25 bug#9560: 24.0.50; c-mode syntax problems Michael Welsh Duggan
                   ` (3 preceding siblings ...)
  2011-10-13  2:33 ` bug#9560: An exact recipe Michael Welsh Duggan
@ 2011-10-22 11:26 ` Alan Mackenzie
  4 siblings, 0 replies; 11+ messages in thread
From: Alan Mackenzie @ 2011-10-22 11:26 UTC (permalink / raw)
  To: 9560-done

Bug fixed.

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-10-22 11:26 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-20 15:25 bug#9560: 24.0.50; c-mode syntax problems Michael Welsh Duggan
     [not found] ` <handler.9560.B.131653264320111.ack@debbugs.gnu.org>
2011-09-20 15:34   ` bug#9560: Acknowledgement (24.0.50; c-mode syntax problems) Michael Welsh Duggan
2011-10-02 18:24 ` bug#9560: A dribble file of an emacs -Q session that triggers the problem Michael Welsh Duggan
2011-10-10  4:15 ` bug#9560: Cache information during failure Michael Welsh Duggan
2011-10-13  2:33 ` bug#9560: An exact recipe Michael Welsh Duggan
2011-10-19 10:16   ` Alan Mackenzie
2011-10-19 13:45     ` Michael Welsh Duggan
2011-10-19 17:39       ` Alan Mackenzie
2011-10-20 11:42       ` Alan Mackenzie
2011-10-21  1:42         ` Michael Welsh Duggan
2011-10-22 11:26 ` bug#9560: Bug #9560 fixed Alan Mackenzie

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).