Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 185675
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T15:30:44+00:00 2026-05-11T15:30:44+00:00

I have a daemon that reads a configuration file in order to know where

  • 0

I have a daemon that reads a configuration file in order to know where to write something. In the configuration file, a line like this exists:

output = /tmp/foo/%d/%s/output 

Or, it may look like this:

output = /tmp/foo/%s/output/%d 

… or simply like this:

output = /tmp/foo/%s/output 

… or finally:

output = /tmp/output 

I have that line as cfg->pathfmt within my program. What I am trying to do now is to come up with some clever way of using it.

A little more explanation, the path can contain up to two components to be formatted. %d will be expanded as a job ID (int), %s as a job name (string). The user may want to use one, both or none in the configuration file. I need to know what they want and in what order before I finally pass it to snprintf(). I can kind of narrow it down, but I keep wanting to talk to strtok() and that seems ugly.

I want to give users this kind of flexibility, however I’m getting lost looking for a sensible, portable way to implement it. I’m also at a complete and total loss for how to begin searching for this.

I’d be very happy if:

  • Someone could help me narrow down the search phrase to find good examples
  • Someone could post a link to some OSS project implementing this
  • Someone could post some psuedo code

I don’t want the code written for me, I’m just really stuck on what (I think) should be something very simple and need some help taking the first bite. I really feel like I’m over thinking and overlooking the obvious.

The end result should be a boolean function like this:

bool output_sugar(const char *fmt, int jobid, const char *jobname, struct job *j); 

It would then call snprintf() (sensibly) on j->outpath, returning false if some kind of garbage (i.e. % followed by something not s, d or %) is in the config line (or its null). The sanity checks are easy, I’m just having a bit of a time getting the number (and order) of arguments to format correct.

Thanks in advance. Also, feel free to edit this title if you have the reputation to do so, as I said, I’m not quite sure how to ask the question in a single line. I think what I need is a parser, but it feels awkward using a full blown lexer / parser to handle one simple string.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T15:30:44+00:00Added an answer on May 11, 2026 at 3:30 pm

    Yes, you need a parser of some sort. It need not be complex, though:

    void format_filename(const char *fmt, int jobid, const char *jobname,                      char *buffer, size_t buflen) {     char *end = buffer + buflen - 1;     const char *src = fmt;     char *dst = buffer;     char c;     assert(buffer != 0 && fmt != 0 && buflen != 0 && jobname != 0);     while ((c = *src++) != '\0')     {         if (dst >= end)             err_exit('buffer overflow in %s(): format = %s\n',                      __func__, fmt);         else if (c != '%')             *dst++ = c;         else if ((c = *src++) == '\0' || c == '%')         {             *dst++ = '%';             if (c == '\0')                 break;         }         else if (c == 's')         {             size_t len = strlen(jobname);             if (len > end - dst)                 err_exit('buffer overflow on jobname in %s(): format = %s\n',                          __func__, fmt);             else             {                 strcpy(dst, jobname);                 dst += len;             }         }         else if (c == 'd')         {              int nchars = snprintf(dst, end - dst, '%d', jobid);              if (nchars < 0 || nchars >= end - dst)                  err_exit('format error on jobid in %s(); format = %s\n',                           __func__, fmt);              dst += nchars;         }         else             err_exit('invalid format character %d in %s(): format = %s\n',                      c, __func__, fmt);     }     *dst = '\0'; } 

    Now tested code. Note that it supports the ‘%%’ notation to allow the user to embed a single ‘%’ in the output. Also, it treats a single ‘%’ at the end of the string as valid and equivalent to ‘%%’. It calls err_exit() on error; you can choose alternative error strategies as suits your system. I simply assume you have included <assert.h>, <stdio.h> and <string.h> and the header for the err_exit() (variadic) function.


    Test code…

    #include <stdio.h> #include <string.h> #include <stdarg.h> #include <assert.h>  static void err_exit(const char *fmt, ...) {     va_list args;     va_start(args, fmt);     vfprintf(stderr, fmt, args);     va_end(args);     exit(1); } 

    … then format_filename() as above, then …

    #define DIM(x) (sizeof(x)/sizeof(*(x)))  static const char *format[] = {     '/tmp/%d/name/%s',     '/tmp/%s/number/%d',     '/tmp/%s.%d%%',     '/tmp/%', };  int main(void) {     char buffer[64];     size_t i;      for (i = 0; i < DIM(format); i++)     {         format_filename(format[i], 1234, 'job-name', buffer, sizeof(buffer));         printf('fmt = %-20s; name = %s\n', format[i], buffer);     }      return(0); } 
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

im looking to write a daemon that: reads a message from a queue (sqs,
I have a daemon that accepts socket connections and reads or writes a dynamic
I have a command-line application called xooky_nabox that was programmed using c++. It reads
I have a daemon that forks the process. This daemon access a database using
I have a Tomcat application that requires multiple passwords on startup. My current configuration
I'm designing a daemon that will continuously read lines from a single text file
I have this Python based service daemon which is doing a lot of multiplexed
I try to write a daemon in python. But I have no idea how
I don't know if this is the right place to ask question like this,
I have a table in MySQL 5 (InnoDB) that is used as a daemon

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.