]> git.mar77i.info Git - perftrace/commitdiff
break up source files, fix get_field_labels
authormar77i <mar77i@protonmail.ch>
Sun, 22 Mar 2026 10:03:05 +0000 (11:03 +0100)
committermar77i <mar77i@protonmail.ch>
Sun, 22 Mar 2026 10:03:05 +0000 (11:03 +0100)
Makefile
list.h [new file with mode: 0644]
parse_args.c [new file with mode: 0644]
parse_args.h [new file with mode: 0644]
perftrace.c

index fb1598b8bd8c99561a68fdc6c6cacdf8a24edfb4..56ff05a1da2edba3a5ed9168081fc18c37d3dab1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ LDLIBS +=
 
 all: perftrace work_some
 
-perftrace: perftrace.o
+perftrace: perftrace.o parse_args.o
 work_some: work_some.o
 
 include global.mk
diff --git a/list.h b/list.h
new file mode 100644 (file)
index 0000000..a924630
--- /dev/null
+++ b/list.h
@@ -0,0 +1,38 @@
+
+// list.h
+
+#ifndef LIST_H
+#define LIST_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct list {
+    size_t len, allo;
+    void *data;
+};
+
+#define LIST_EMPTY ((struct list){ 0, 0, NULL })
+#define LIST_ITEMS(l, t) ((t*)(l).data)
+#define LIST_POS(p, l, t) (size_t)((p) - LIST_ITEMS((l), t))
+#define LIST_AT(l, i, t) (LIST_ITEMS((l), t) + i)
+
+static inline int list_maybe_grow(
+    struct list *l, size_t new_len, size_t item_size
+) {
+    void *np;
+    if (new_len <= l->allo)
+        return 0;
+    do
+        l->allo = l->allo ? l->allo * 2 : 8;
+    while (new_len > l->allo);
+    np = realloc(l->data, l->allo * item_size);
+    if (np == NULL) {
+        perror("realloc");
+        return -1;
+    }
+    l->data = np;
+    return 0;
+}
+
+#endif // LIST_H
diff --git a/parse_args.c b/parse_args.c
new file mode 100644 (file)
index 0000000..25494b9
--- /dev/null
@@ -0,0 +1,116 @@
+
+// parse_args.c
+
+#include <string.h>
+#include <unistd.h>
+
+#include "parse_args.h"
+
+static inline int parse_pid(const char *ptr, struct arg_pid_item *new_item) {
+    unsigned long pid = 0;
+    do {
+        if (parse_unsigned_long(&pid, *ptr, NULL) < 0)
+            return -1;
+        ptr++;
+    } while (*ptr != '\0' && *ptr != '+' && *ptr != '*');
+    *new_item = (struct arg_pid_item){ pid, *ptr };
+    if (ptr[0] != '\0' && ptr[1] != '\0')
+        return -1;
+    return 0;
+}
+
+static inline int parse_arg_pid(int argc, char ***argv, struct list *arg_pids) {
+    if (
+        list_maybe_grow(
+            arg_pids, ++arg_pids->len, sizeof (struct arg_pid_item)
+        ) < 0
+    )
+        return -1;
+    if ((**argv)[5] == '=') {
+        if (
+            parse_pid(
+                **argv + 6,
+                LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
+            ) < 0
+        )
+            return -1;
+    } else if ((**argv)[5] == '\0') {
+        if (
+            --argc == 0
+            || parse_pid(
+                *++(*argv),
+                LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
+            ) < 0
+        )
+            return -1;
+    } else
+        return -1;
+    return argc;
+}
+
+static inline int parse_delay(const char *ptr, struct timeval *delay) {
+    register unsigned long fractions;
+    *delay = (struct timeval){ 0, 0 };
+    for (; *ptr != '\0' && *ptr != '.'; ptr++)
+        if (parse_unsigned_long((unsigned long*)&delay->tv_sec, *ptr, NULL) < 0)
+            return -1;
+    ptr += *ptr != '\0';
+    for (
+        fractions = MICRO_IN_SEC / 10;
+        *ptr && fractions > 0;
+        ptr++, fractions /= 10
+    )
+        if (*ptr < '0' || *ptr > '9')
+            return -1;
+        else
+            delay->tv_usec += fractions * (*ptr - '0');
+    return 0;
+}
+
+static inline int parse_arg_delay(
+    int argc, char ***argv, struct timeval *delay
+) {
+    long clock_ticks;
+    if ((**argv)[7] == '=') {
+        if (parse_delay(**argv + 8, delay) < 0)
+            return -1;
+    } else if ((**argv)[7] == '\0') {
+        if (--argc == 0 || parse_delay(*++(*argv), delay) < 0)
+            return -1;
+    } else
+        return -1;
+    clock_ticks = sysconf(_SC_CLK_TCK);
+    if (
+        (clock_ticks <= 1 && delay->tv_sec < 1) || (
+            delay->tv_sec < 1 && delay->tv_usec < MICRO_IN_SEC / clock_ticks
+        )
+    ) {
+        fprintf(stderr, "Error: delay too small!\n");
+        return -1;
+    }
+    return argc;
+}
+
+int parse_args(
+    int argc,
+    char **argv,
+    struct list *pids,
+    struct timeval *delay,
+    int *humanize_mem
+) {
+    for (argc--, argv++; argc > 0; argc--, argv++) {
+        if (strncmp(*argv, "--pid", 5) == 0)
+            argc = parse_arg_pid(argc, &argv, pids);
+        else if (strncmp(*argv, "--delay", 7) == 0)
+            argc = parse_arg_delay(argc, &argv, delay);
+        else if (strcmp(*argv, "--humanize") == 0)
+            *humanize_mem = 1;
+        else
+            argc = -1;
+        if (argc == -1) {
+            fprintf(stderr, "Error: Could not process argument: '%s'\n", *argv);
+            return -1;
+        }
+    }
+    return 0;
+}
diff --git a/parse_args.h b/parse_args.h
new file mode 100644 (file)
index 0000000..ef42c17
--- /dev/null
@@ -0,0 +1,42 @@
+
+// parse_args.h
+
+#ifndef PARSE_ARGS_H
+#define PARSE_ARGS_H
+
+#include "list.h"
+
+#define MICRO_IN_SEC 1000000
+
+struct arg_pid_item {
+    pid_t pid;
+    char mode;
+};
+
+int parse_args(
+    int argc,
+    char **argv,
+    struct list *pids,
+    struct timeval *delay,
+    int *humanize_mem
+);
+
+static inline int parse_unsigned_long(
+    unsigned long *result, char c, char *label
+) {
+    register unsigned long new_value = 10 * *result + c - '0';
+    if (c >= '0' && new_value / 10 == *result) {
+        *result = new_value;
+        return 0;
+    }
+    if (label)
+        fprintf(
+            stderr,
+            "Error: %s: invalid character or overflow ('%c')\n",
+            label,
+            c
+        );
+    return -1;
+}
+
+#endif // PARSE_ARGS_H
index 01502e5c6258057720f055b3d34d5564024e089f..1af54354677aac51566d4ba30f61a1bda48109b3 100644 (file)
 #include <fcntl.h>
 #include <limits.h>
 #include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include <sys/time.h>
 
+#include "list.h"
+#include "parse_args.h"
+
 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
 
-#define MICRO_IN_SEC 1000000
 #define NANO_IN_SEC 1000000000
 #define TIMESPEC_TO_DOUBLE(t) \
     ((double)(t).tv_sec + (double)(t).tv_nsec / NANO_IN_SEC)
 #define TIMESPEC_ISZERO(t) ((t).tv_sec == 0 && (t).tv_nsec == 0)
 
-struct list {
-    size_t len, allo;
-    void *data;
-};
-#define LIST_EMPTY ((struct list){ 0, 0, NULL })
-#define LIST_ITEMS(l, t) ((t*)(l).data)
-#define LIST_POS(p, l, t) (size_t)((p) - LIST_ITEMS((l), t))
-#define LIST_AT(l, i, t) (LIST_ITEMS((l), t) + i)
-
-static inline int list_maybe_grow(
-    struct list *l, size_t new_len, size_t item_size
-) {
-    void *np;
-    if (new_len <= l->allo)
-        return 0;
-    do
-        l->allo = l->allo ? l->allo * 2 : 8;
-    while (new_len > l->allo);
-    np = realloc(l->data, l->allo * item_size);
-    if (np == NULL) {
-        perror("realloc");
-        return -1;
-    }
-    l->data = np;
-    return 0;
-}
-
-struct arg_pid_item {
-    pid_t pid;
-    char mode;
-};
-
-static inline int parse_unsigned_long(
-    unsigned long *result, char c, char *label
-) {
-    register unsigned long new_value = 10 * *result + c - '0';
-    if (c >= '0' && new_value / 10 == *result) {
-        *result = new_value;
-        return 0;
-    }
-    if (label)
-        fprintf(
-            stderr,
-            "Error: %s: invalid character or overflow ('%c')\n",
-            label,
-            c
-        );
-    return -1;
-}
-
-static inline int parse_pid(const char *ptr, struct arg_pid_item *new_item) {
-    unsigned long pid = 0;
-    do {
-        if (parse_unsigned_long(&pid, *ptr, NULL) < 0)
-            return -1;
-        ptr++;
-    } while (*ptr != '\0' && *ptr != '+' && *ptr != '*');
-    *new_item = (struct arg_pid_item){ pid, *ptr };
-    if (ptr[0] != '\0' && ptr[1] != '\0')
-        return -1;
-    return 0;
-}
-
-static inline int parse_arg_pid(int argc, char ***argv, struct list *arg_pids) {
-    if (
-        list_maybe_grow(
-            arg_pids, ++arg_pids->len, sizeof (struct arg_pid_item)
-        ) < 0
-    )
-        return -1;
-    if ((**argv)[5] == '=') {
-        if (
-            parse_pid(
-                **argv + 6,
-                LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
-            ) < 0
-        )
-            return -1;
-    } else if ((**argv)[5] == '\0') {
-        if (
-            --argc == 0
-            || parse_pid(
-                *++(*argv),
-                LIST_ITEMS(*arg_pids, struct arg_pid_item) + arg_pids->len - 1
-            ) < 0
-        )
-            return -1;
-    } else
-        return -1;
-    return argc;
-}
-
-static inline int parse_delay(const char *ptr, struct timeval *delay) {
-    register unsigned long fractions;
-    *delay = (struct timeval){ 0, 0 };
-    for (; *ptr != '\0' && *ptr != '.'; ptr++)
-        if (parse_unsigned_long((unsigned long*)&delay->tv_sec, *ptr, NULL) < 0)
-            return -1;
-    ptr += *ptr != '\0';
-    for (
-        fractions = MICRO_IN_SEC / 10;
-        *ptr && fractions > 0;
-        ptr++, fractions /= 10
-    )
-        if (*ptr < '0' || *ptr > '9')
-            return -1;
-        else
-            delay->tv_usec += fractions * (*ptr - '0');
-    return 0;
-}
-
-static inline int parse_arg_delay(
-    int argc, char ***argv, struct timeval *delay
-) {
-    long clock_ticks;
-    if ((**argv)[7] == '=') {
-        if (parse_delay(**argv + 8, delay) < 0)
-            return -1;
-    } else if ((**argv)[7] == '\0') {
-        if (--argc == 0 || parse_delay(*++(*argv), delay) < 0)
-            return -1;
-    } else
-        return -1;
-    clock_ticks = sysconf(_SC_CLK_TCK);
-    if (
-        (clock_ticks <= 1 && delay->tv_sec < 1) || (
-            delay->tv_sec < 1 && delay->tv_usec < MICRO_IN_SEC / clock_ticks
-        )
-    ) {
-        fprintf(stderr, "Error: delay too small!\n");
-        return -1;
-    }
-    return argc;
-}
-
-int parse_args(
-    int argc,
-    char **argv,
-    struct list *pids,
-    struct timeval *delay,
-    int *humanize_mem
-) {
-    for (argc--, argv++; argc > 0; argc--, argv++) {
-        if (strncmp(*argv, "--pid", 5) == 0)
-            argc = parse_arg_pid(argc, &argv, pids);
-        else if (strncmp(*argv, "--delay", 7) == 0)
-            argc = parse_arg_delay(argc, &argv, delay);
-        else if (strcmp(*argv, "--humanize") == 0)
-            *humanize_mem = 1;
-        else
-            argc = -1;
-        if (argc == -1) {
-            fprintf(stderr, "Error: Could not process argument: '%s'\n", *argv);
-            return -1;
-        }
-    }
-    return 0;
-}
 
 static int alarm_set, int_set, page_size;
 
@@ -205,27 +47,21 @@ struct pid_item {
 };
 
 static inline void get_field_labels(char digits, char *buffer) {
-    const char *s = "ppidvsizerss";
+    const char *s = "ppid\0vsize\0rss";
     char *ptr = buffer;
     for (digits &= 7; digits; digits >>= 1) {
         if (!(digits & 1)) {
-            s += 4;
-            if (*s != 'u')
-                s++;
+            s += 5 + (s[4] != '\0');
             continue;
         }
         if (ptr > buffer) {
             *ptr++ = ',';
             *ptr++ = ' ';
         }
-        *ptr++ = *s++;
-        *ptr++ = *s++;
-        *ptr++ = *s++;
-        if (!*s)
-            break;
-        *ptr++ = *s++;
-        if (*s != 'u')
+        do
             *ptr++ = *s++;
+        while (*s);
+        s++;
     }
     *ptr = '\0';
 }