Programming Obsession
---Lately almost all that I’ve been doing is working on a sophisticated program mainly for my own use at this point. I love it, but each tiny thing I think about tends to blossom into so many little chores that I can barely get them all done each day. This function below is one tiny part of the overall program, and is actually much more complicated than it needed to be in the long run. The reason for this was because I developed it before the thought had occurred to me that it would be a good idea to limit the allowed path-name sizes up front to much less than the common limit of 255 character-long paths in Windows. I say “common” because it is possible to have longer path names now, but most programs still don’t recognize this fact, so it causes a lot of things to bomb if you allow path-names longer than 255 characters, even though Windows does allow them now, at least on the better file systems. Anyway, so I just got done today adding in this new lower limit, which would basically keep this function from ever needing to try to strip away at names to make them fit as I’ve done below. My idea for doing this was that I wanted a way to avoid bombing the program out either by core-dump or via graceful exit in such cases, and I thought this would be kind of fun. After all, who knows what odd path-names might end up resulting from such nearly-random chopping away at various parts of them! LOL. And I felt somewhat proud of how complicated that I’d ended up making it even though the logic still seems correct and it therefore still should work, my undoubtedly putting in way too many “assert” statements just to be sure that I’m not wrong about this, being that what assert does is intentionally bomb the program if the resulting calculation that it’s making ends up being zero. So as long as all assert statements continually end up with Non-zero values than in them then everything is fine and the program logic is okay. So what this specific function does is it is an inner part to my own mktemp type of function where a temporary file name (or folder) that has a unique name can be created. All that this inner function, formtempname, does here then is to come up with a sequence of likely names, and then it is the job of the outer function mymktemp to actually try creating the file/folder using the resulting name from this function. And as long as it keeps repeating the same calls to this function, like when it needs multiple temp-files all at once, then it will quickly get a set of unique temporary file names having different sequential numbers within their names. And the reason that I developed this instead of using the normal mktemp or smktemp functions? Well...frankly...because although I’m compiling on Windows via Cygwin’s source code, I don’t actually INCLUDE Cygwin’s functions while compiling, which allows me to remain free from having to use their DLL file each time I run my programs. The only drawback to this, however is that this forces me to instead link with the Mingw set of Linux-like functions, and some of them just aren’t really either there or working correctly. And mktemp and smktemp are examples of some of these functions that just aren’t working in Mingw’s set of supplied functions. So anyway, doing all of this intense programming has just made me become extremely obsessed with it lately to my admitted detriment, but hopefully I’ll be able to get a little better handle on trying to get some of my other things done as well. I just get literally like a dog with a bone it would seem when it comes to my working on C programming. C++ is fun as well but it honestly takes me a bit more time, whereas I’m really in a rush right now to try to develop this program as quickly as I can for myself. Oh and by the way, the reason that I write so obnoxiously to others with all of my source-code so compressed together like you see here is because I have a horrible memory. Therefore, I’ve found, that the more of it I can see at once on the screen, the faster and easier it is for me to both write and maintain programs. It’s just the way I have to do it given my poor memory. Once something runs of the screen, it just becomes almost instantly vague to me. So for anyone interested, here is this example of a complicated function that I just wrote for my program a couple of days ago: :)
char *formtempname(char *fileptrn, char *suffix) { //Form 1st/Nxt TempNameToTry: //^CAUTION: filtptrn is Alwys written to here by using '?' cut to know it's Cont //^On first call per usage, ONE '?' at end of fileptrn starts the pattern // area; Also, if a suffix is given (NON-0), ONE '?' anywhere in it, if // present at all, will also be replaced to match the new pattern that is set // per each call; ONE folder slash is also permitted within the suffix if // desired (with NO limits of them within the fileptrn string), although it // can come only BEFORE the pattern character whenever a pattern is also // present within the suffix (usually used for Auto-creating an inner-folder): //TrueMax: MPL+12+11+(12+11)+(MPL-1)=MPL+46+254=555 \<ItemName>?<.Extnsn> //RsnblMax:<PathLen>+12+11+(12+11)+(MPL-<PathLen>)=46+MPL=300 \<InnerFileNam> //.../a/a.ssc //<MaxPathLen=249> (With Min 6 extra needed for SS Filenames): register int in1, in2, in3, in4, in5, in6; register char *cp1, *cp2, *cp3, *ep2, *ep3; char cxsuf[MPS + 23]; //The currently altered suffix if a suffix is provided static int seq; //The sequence number used in forming temp-name static int cblen, pidnum, pidl; //Len of Crnt BaseArea of name; ProcID# & Len static char crntname[MPS + 46]; //The Crnt name based on the provided pattern static char *ptrnat = 0; //Location to use as start of pattern area in name static char *altrat; //Location to use as start of altered area in name static char *oldsuf; //Pointer to the given suffix from start of hunt //static char slash; //What folder-slash-character is being used if (fileptrn[in1 = strlen(fileptrn) - 1] == '?') { //Starting a new hunt: fileptrn[in1] = 0; //Chop original Ptrn-Marker to know not new hunt ADJPATH(fileptrn); //Safeguard from overrunning Window's Max path length strcpy(crntname, fileptrn); //Copy the base-name cblen = strlen(crntname); //Length of the base-name assert(!rindex(crntname, '?')); //Only ONE question mark allowed! oldsuf = suffix; //Retain the original suffix-pointer to assure stays same ptrnat = crntname + cblen; //Start of the pattern area pidnum = getpid(); //Get the process ID# of this instance of this program altrat = ptrnat + (pidl = sprintf(ptrnat, "-%d-", pidnum)); //BegOfAltrdArea seq = -1; //Reset the sequence number to start at the beginning //if (!(slash = GETSLASH(fileptrn, !suffix))) g.slash = GETSLASH(suffix, 1); }else assert(ptrnat && suffix==oldsuf && !strncmp(fileptrn, crntname, cblen)); if (++seq < 0) seq = 0; //Restart if wraps from using all 0x7fffffff Postv #'s in2 = sprintf(altrat, "%dT", seq); //Form the remainder of the temp-name if (suffix) { //A suffix was provided so hunt for pattern-char within it: SAFECOPYPATH(cxsuf, suffix); //Safely create an alterable copy of the suffix cp1 = rindex(cxsuf, '?'); //Find location of pattern in suffix if present assert((ep3 = strchr(cxsuf, g.slash)) == rindex(cxsuf, g.slash) //Only1Slash && (!cp1 || ep3 < cp1)); //^Assure the proper format of the suffix: if (ep3) ep3++; else ep3 = cxsuf; //Stopping point for Revrs Srchs in suffix if (cp1) *cp1 = 0; //Split suffix at its pattern assert(!rindex(cxsuf, '?')); //Only ONE question mark allowed! in3 = strlen(cxsuf); //LengthOfFirstPartOfSuffix (orEntiretyWhenNoPattern) //Set and/or adjust all sizes and positions of the parts within the suffix: //in3+in5= cp1-cxsuf+in3_-((cp1-cxsuf)+1)= cp1-cxsuf+in3_-cp1+cxsuf-1=in3_-1 if (cp1) in5 = in3, in3 = cp1 - cxsuf, in4 = pidl + in2, in5 -= in3 + 1; else cp1 = cxsuf + in3, in4 = in5 = 0; //No pattern was found in suffix }else cp1 = 0, in3 = in4 = in5 = 0; //No suffix given so no part-sizes exist //Safeguard overrunning Window's maximum path length: if ((cblen + pidl + in2) + (in3 + in4 + in5) > MPL) { //PathTooLongSoShorten: ep2 = FINDBEGOFPART1(crntname, g.slash); //Where to stop going Bkwd in Path cp2 = ptrnat; //Starting at start of base-name's pattern area seq = 0, in2 = 2; //Starting over with fresh numbers and their size if (in4) { //A patterned-suffix so see if Choppng pre-pattern areas helps: in4 = pidl + in2; //Size of suffix-pattern changed due to fresh numbers cp3 = cp1; //Starting at start of suffix's pattern area (going backward) in6 = 1; //BothNamesStillShortenableAlthoughNotYetSeenAsAPossibleNamePair for (;;) { //Try shortening names OR bomb Prgm if doesn't resolve issue: //NOTE: This ultra-complex section just HAPPENED, WO/advanced planning: //If the two names might possibly be a possible matching name-pair: if (ABS(in6) == 1 && cp2 > ep2 && cp3 > ep3 && cp2[-1] == cp3[-1]) { --cp2, --cblen, --cp3, --in3, in6 = -1; //Shorten both bases one Char if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; continue; //Keep trying to shorten both names AtSameTime AsMatchngPair }else if (in6 < 0) { //^Shorten both base-name and suffix's base-portn //assert(cp2 > ep2 || cp3 > ep3); //NamePair could not be ShortendMore in6 = 2; //Matching so far likely a coincidence so do rest free-style }else if (in6 == 1) in6 = 2; //NamePairMtchngFailed so do rest FreeStyle //Do free-style Trunctng of either name NonSynchrnsly b/c not name-pair: if (in6 && cp3 > ep3) { //Suffix still okay to trunctate another Char: --cp3, --in3; //Shorten suffix's first-part of name by one Char if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; }else in6 = 0; //Suffix's name couldn't be shortened any further if (cp2 > ep2) { //Base-name okay to truncate further: --cp2, --cblen; //Shorten the base-name by one Char if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; }else { //assert(in6); //Neither name could be shortened any further if (!in6) { //LastResort if neither name could be Shortnd any further: assert(ep2 > crntname || ep3 > cxsuf); //Avoid infinite loops! if (ep2 > crntname) ep2--; if (ep3 > cxsuf) ep3--; in6 = 2; } } } //^Eats away at both names in-sync or just one when other is blocked }else if (suffix) { //A Non-patterned-suffix SoSeeIfChoppingEitherHelps: cp3 = cp1; //Starting at end of suffix in6 = 1; //Base-name is currently still shortenable for (;;) { //Try shortening names OR bomb Prgm if doesn't resolve issue: if (in6 && cp2 > ep2) { //Base-name okay to truncate further: --cp2, --cblen; //Shorten the base-name by one Char if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; continue; //Keep trying to shorten only the base-name first }else in6 = 0; //Base-name couldn't be shortened any further //assert(cp3 > ep3); //Fail if suffix not okay to truncate further if (cp3 <= ep3) { //Last resort if suffix not okay to truncate further: assert(ep2 > crntname && ep3 == cxsuf); //Avoid infiinite loops! ep2--; in6 = 1; continue; } --cp3, --in3; //Shorten suffix by one Char //^So both names stuck if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; } //^Eats away base-name first then suffix after no more base-name }else { //No suffix was given so see if chopping just base-name helps: for (;;) { //Try shortening BaseName OR bomb Prgm if doesn't solve issue: //assert(cp2 > ep2); //Fail if base-name not okay to truncate further if (cp2 <= ep2) { //LastResort if BaseName not okay to truncate further: assert(ep2 > crntname); //Avoid infiinite loops! ep2--; continue; } --cp2, --cblen; //Shorten the base-name by one Char //^So stuck now if ((cblen + pidl + in2) + (in3 + in4 + in5) < MPS) break; } //^Eats away at base-name until either short enough or bombs program } altrat = (ptrnat = cp2) + pidl; if (cp1) *cp3 = 0; //AdjustToNewNameEndings sprintf(ptrnat, "-%d-0T", pidnum); //And reform the pattern area in BaseName } //vProceed since found an altered temp-name that is short enough: if (suffix) {if (!in4) strcpy(altrat + in2, cxsuf); else //Append suffix: sprintf(altrat + in2, "%s-%d-%dT%s", cxsuf, pidnum, seq, cp1 + 1);} ADJPATH(crntname); //One last fail-safe check to assure size OK return crntname; //Return pointer to next try for a pattern-formed temp-name }
















