Task: Update a configuration file

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define strcomp(X, Y) strcasecmp(X, Y)

struct option
{ const char *name, *value; 
  int flag; };


struct option updlist[] =
{ { "NEEDSPEELING", NULL },
  { "SEEDSREMOVED", "" },
  { "NUMBEROFBANANAS", "1024" },
  { "NUMBEROFSTRAWBERRIES", "62000" },
  { NULL, NULL } };

int output_opt(FILE *to, struct option *opt)
{ if (opt->value == NULL)
    return fprintf(to, "; %s\n", opt->name);
  else if (opt->value[0] == 0)
    return fprintf(to, "%s\n", opt->name);
  else 
    return fprintf(to, "%s %s\n", opt->name, opt->value); }

int update(FILE *from, FILE *to, struct option *updlist) 
{ char line_buf[256], opt_name[128];
  int i;
  for (;;)
  { size_t len, space_span, span_to_hash;
    if (fgets(line_buf, sizeof line_buf, from) == NULL)
      break;
    len = strlen(line_buf);
    space_span = strspn(line_buf, "\t ");
    span_to_hash = strcspn(line_buf, "#");
    if (space_span == span_to_hash)
      goto line_out;
    if (space_span == len)
      goto line_out;
    if ((sscanf(line_buf, "; %127s", opt_name) == 1) ||
        (sscanf(line_buf, "%127s", opt_name) == 1))
    { int flag = 0;
      for (i = 0; updlist[i].name; i++)
      { if (strcomp(updlist[i].name, opt_name) == 0)
        { if (output_opt(to, &updlist[i]) < 0)
            return -1;
          updlist[i].flag = 1;
          flag = 1; } }
      if (flag == 0)
        goto line_out; }
    else
  line_out: 
      if (fprintf(to, "%s", line_buf) < 0)
        return -1;
    continue; }
  { for (i = 0; updlist[i].name; i++)
    { if (!updlist[i].flag)
        if (output_opt(to, &updlist[i]) < 0)
          return -1; } }
  return feof(from) ? 0 : -1; }

int main(void)
{ if (update(stdin, stdout, updlist) < 0)
  { fprintf(stderr, "failed\n");
    return (EXIT_FAILURE); }
  return 0; }





Java: import java.io.*;
import java.util.*;
import java.util.regex.*;

public class UpdateConfig {

    public static void main(String[] args) {
        if (args[0] == null) {
            System.out.println("filename required");

        } else if (readConfig(args[0])) {
            enableOption("seedsremoved");
            disableOption("needspeeling");
            setOption("numberofbananas", "1024");
            addOption("numberofstrawberries", "62000");
            store();
        }
    }

    private enum EntryType {
        EMPTY, ENABLED, DISABLED, COMMENT
    }

    private static class Entry {
        EntryType type;
        String name, value;

        Entry(EntryType t, String n, String v) {
            type = t;
            name = n;
            value = v;
        }
    }

    private static Map<String, Entry> entries = new LinkedHashMap<>();
    private static String path;

    private static boolean readConfig(String p) {
        path = p;

        File f = new File(path);
        if (!f.exists() || f.isDirectory())
            return false;

        String regexString = "^(;*)\\s*([A-Za-z0-9]+)\\s*([A-Za-z0-9]*)";
        Pattern regex = Pattern.compile(regexString);

        try (Scanner sc = new Scanner(new FileReader(f))){
            int emptyLines = 0;
            String line;
            while (sc.hasNext()) {
                line = sc.nextLine().trim();

                if (line.isEmpty()) {
                    addOption("" + emptyLines++, null, EntryType.EMPTY);

                } else if (line.charAt(0) == '#') {
                    entries.put(line, new Entry(EntryType.COMMENT, line, null));

                } else {
                    line = line.replaceAll("[^a-zA-Z0-9\\x20;]", "");
                    Matcher m = regex.matcher(line);

                    if (m.find() && !m.group(2).isEmpty()) {

                        EntryType t = EntryType.ENABLED;
                        if (!m.group(1).isEmpty())
                            t = EntryType.DISABLED;

                        addOption(m.group(2), m.group(3), t);
                    }
                }
            }
        } catch (IOException e) {
            System.out.println(e);
        }
        return true;
    }

    private static void addOption(String name, String value) {
        addOption(name, value, EntryType.ENABLED);
    }

    private static void addOption(String name, String value, EntryType t) {
        name = name.toUpperCase();
        entries.put(name, new Entry(t, name, value));
    }

    private static void enableOption(String name) {
        Entry e = entries.get(name.toUpperCase());
        if (e != null)
            e.type = EntryType.ENABLED;
    }

    private static void disableOption(String name) {
        Entry e = entries.get(name.toUpperCase());
        if (e != null)
            e.type = EntryType.DISABLED;
    }

    private static void setOption(String name, String value) {
        Entry e = entries.get(name.toUpperCase());
        if (e != null)
            e.value = value;
    }

    private static void store() {
        try (PrintWriter pw = new PrintWriter(path)) {
            for (Entry e : entries.values()) {
                switch (e.type) {
                    case EMPTY:
                        pw.println();
                        break;
                    case ENABLED:
                        pw.format("%s %s%n", e.name, e.value);
                        break;
                    case DISABLED:
                        pw.format("; %s %s%n", e.name, e.value);
                        break;
                    case COMMENT:
                        pw.println(e.name);
                        break;
                    default:
                        break;
                }
            }
            if (pw.checkError()) {
                throw new IOException("writing to file failed");
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}